1 /* $OpenBSD: btrace.c,v 1.95 2025/01/23 11:17:32 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 2019 - 2023 Martin Pieuchot <mpi@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/ioctl.h> 20 #include <sys/stat.h> 21 #include <sys/syscall.h> 22 #include <sys/queue.h> 23 24 #include <assert.h> 25 #include <err.h> 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <limits.h> 29 #include <locale.h> 30 #include <paths.h> 31 #include <signal.h> 32 #include <stdarg.h> 33 #include <stdbool.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <time.h> 38 #include <unistd.h> 39 40 #include <dev/dt/dtvar.h> 41 42 #include "btrace.h" 43 #include "bt_parser.h" 44 45 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 46 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 47 48 /* 49 * Maximum number of operands an arithmetic operation can have. This 50 * is necessary to stop infinite recursion when evaluating expressions. 51 */ 52 #define __MAXOPERANDS 5 53 54 #define __PATH_DEVDT "/dev/dt" 55 56 __dead void usage(void); 57 char *read_btfile(const char *, size_t *); 58 59 /* 60 * Retrieve & parse probe information. 61 */ 62 void dtpi_cache(int); 63 void dtpi_print_list(int); 64 const char *dtpi_func(struct dtioc_probe_info *); 65 int dtpi_is_unit(const char *); 66 struct dtioc_probe_info *dtpi_get_by_value(const char *, const char *, 67 const char *); 68 69 /* 70 * Main loop and rule evaluation. 71 */ 72 void probe_bail(struct bt_probe *); 73 const char *probe_name(struct bt_probe *); 74 void rules_do(int); 75 int rules_setup(int); 76 int rules_apply(int, struct dt_evt *); 77 void rules_teardown(int); 78 int rule_eval(struct bt_rule *, struct dt_evt *); 79 void rule_printmaps(struct bt_rule *); 80 81 /* 82 * Language builtins & functions. 83 */ 84 uint64_t builtin_nsecs(struct dt_evt *); 85 const char *builtin_arg(struct dt_evt *, enum bt_argtype); 86 struct bt_arg *fn_str(struct bt_arg *, struct dt_evt *, char *); 87 int stmt_eval(struct bt_stmt *, struct dt_evt *); 88 void stmt_bucketize(struct bt_stmt *, struct dt_evt *); 89 void stmt_clear(struct bt_stmt *); 90 void stmt_delete(struct bt_stmt *, struct dt_evt *); 91 void stmt_insert(struct bt_stmt *, struct dt_evt *); 92 void stmt_print(struct bt_stmt *, struct dt_evt *); 93 void stmt_store(struct bt_stmt *, struct dt_evt *); 94 bool stmt_test(struct bt_stmt *, struct dt_evt *); 95 void stmt_time(struct bt_stmt *, struct dt_evt *); 96 void stmt_zero(struct bt_stmt *); 97 struct bt_arg *ba_read(struct bt_arg *); 98 struct bt_arg *baeval(struct bt_arg *, struct dt_evt *); 99 const char *ba2hash(struct bt_arg *, struct dt_evt *); 100 long baexpr2long(struct bt_arg *, struct dt_evt *); 101 const char *ba2bucket(struct bt_arg *, struct bt_arg *, 102 struct dt_evt *, long *); 103 int ba2dtflags(struct bt_arg *); 104 105 /* 106 * Debug routines. 107 */ 108 __dead void xabort(const char *, ...); 109 void debug(const char *, ...); 110 void debugx(const char *, ...); 111 void debug_dump_term(struct bt_arg *); 112 void debug_dump_expr(struct bt_arg *); 113 void debug_dump_filter(struct bt_rule *); 114 115 struct dtioc_probe_info *dt_dtpis; /* array of available probes */ 116 size_t dt_ndtpi; /* # of elements in the array */ 117 struct dtioc_arg_info **dt_args; /* array of probe arguments */ 118 119 struct dt_evt bt_devt; /* fake event for BEGIN/END */ 120 #define EVENT_BEGIN 0 121 #define EVENT_END (unsigned int)(-1) 122 uint64_t bt_filtered; /* # of events filtered out */ 123 124 struct syms *kelf, *uelf; 125 126 char **vargs; 127 int nargs = 0; 128 int verbose = 0; 129 int dtfd; 130 volatile sig_atomic_t quit_pending; 131 132 static void 133 signal_handler(int sig) 134 { 135 quit_pending = sig; 136 } 137 138 139 int 140 main(int argc, char *argv[]) 141 { 142 int fd = -1, ch, error = 0; 143 const char *filename = NULL, *btscript = NULL; 144 int showprobes = 0, noaction = 0; 145 size_t btslen = 0; 146 147 setlocale(LC_ALL, ""); 148 149 while ((ch = getopt(argc, argv, "e:lnp:v")) != -1) { 150 switch (ch) { 151 case 'e': 152 btscript = optarg; 153 btslen = strlen(btscript); 154 break; 155 case 'l': 156 showprobes = 1; 157 break; 158 case 'n': 159 noaction = 1; 160 break; 161 case 'p': 162 uelf = kelf_open(optarg); 163 break; 164 case 'v': 165 verbose++; 166 break; 167 default: 168 usage(); 169 } 170 } 171 172 argc -= optind; 173 argv += optind; 174 175 if (argc > 0 && btscript == NULL) 176 filename = argv[0]; 177 178 /* Cannot pledge due to special ioctl()s */ 179 if (unveil(__PATH_DEVDT, "r") == -1) 180 err(1, "unveil %s", __PATH_DEVDT); 181 if (unveil(_PATH_KSYMS, "r") == -1) 182 err(1, "unveil %s", _PATH_KSYMS); 183 if (filename != NULL) { 184 if (unveil(filename, "r") == -1) 185 err(1, "unveil %s", filename); 186 } 187 if (unveil(NULL, NULL) == -1) 188 err(1, "unveil"); 189 190 if (filename != NULL) { 191 btscript = read_btfile(filename, &btslen); 192 argc--; 193 argv++; 194 } 195 196 nargs = argc; 197 vargs = argv; 198 199 if (btscript == NULL && !showprobes) 200 usage(); 201 202 if (btscript != NULL) { 203 error = btparse(btscript, btslen, filename, 1); 204 if (error) 205 return error; 206 } 207 208 if (noaction) 209 return error; 210 211 if (showprobes || g_nprobes > 0) { 212 fd = open(__PATH_DEVDT, O_RDONLY); 213 if (fd == -1) 214 err(1, "could not open %s", __PATH_DEVDT); 215 dtfd = fd; 216 } 217 218 if (showprobes) { 219 dtpi_cache(fd); 220 dtpi_print_list(fd); 221 } 222 223 if (!TAILQ_EMPTY(&g_rules)) 224 rules_do(fd); 225 226 if (fd != -1) 227 close(fd); 228 229 return error; 230 } 231 232 __dead void 233 usage(void) 234 { 235 fprintf(stderr, "usage: %s [-lnv] [-e program | file] [-p file] " 236 "[argument ...]\n", getprogname()); 237 exit(1); 238 } 239 240 char * 241 read_btfile(const char *filename, size_t *len) 242 { 243 FILE *fp; 244 char *fcontent; 245 struct stat st; 246 size_t fsize; 247 248 if (stat(filename, &st)) 249 err(1, "can't stat '%s'", filename); 250 251 fsize = st.st_size; 252 fcontent = malloc(fsize + 1); 253 if (fcontent == NULL) 254 err(1, "malloc"); 255 256 fp = fopen(filename, "r"); 257 if (fp == NULL) 258 err(1, "can't open '%s'", filename); 259 260 if (fread(fcontent, 1, fsize, fp) != fsize) 261 err(1, "can't read '%s'", filename); 262 fcontent[fsize] = '\0'; 263 264 fclose(fp); 265 *len = fsize; 266 return fcontent; 267 } 268 269 void 270 dtpi_cache(int fd) 271 { 272 struct dtioc_probe dtpr; 273 274 if (dt_dtpis != NULL) 275 return; 276 277 memset(&dtpr, 0, sizeof(dtpr)); 278 if (ioctl(fd, DTIOCGPLIST, &dtpr)) 279 err(1, "DTIOCGPLIST"); 280 281 dt_ndtpi = dtpr.dtpr_size / sizeof(*dt_dtpis); 282 dt_dtpis = reallocarray(NULL, dt_ndtpi, sizeof(*dt_dtpis)); 283 if (dt_dtpis == NULL) 284 err(1, NULL); 285 286 dtpr.dtpr_probes = dt_dtpis; 287 if (ioctl(fd, DTIOCGPLIST, &dtpr)) 288 err(1, "DTIOCGPLIST"); 289 } 290 291 void 292 dtai_cache(int fd, struct dtioc_probe_info *dtpi) 293 { 294 struct dtioc_arg dtar; 295 296 if (dt_args == NULL) { 297 dt_args = calloc(dt_ndtpi, sizeof(*dt_args)); 298 if (dt_args == NULL) 299 err(1, NULL); 300 } 301 302 if (dt_args[dtpi->dtpi_pbn - 1] != NULL) 303 return; 304 305 dt_args[dtpi->dtpi_pbn - 1] = reallocarray(NULL, dtpi->dtpi_nargs, 306 sizeof(**dt_args)); 307 if (dt_args[dtpi->dtpi_pbn - 1] == NULL) 308 err(1, NULL); 309 310 dtar.dtar_pbn = dtpi->dtpi_pbn; 311 dtar.dtar_size = dtpi->dtpi_nargs * sizeof(**dt_args); 312 dtar.dtar_args = dt_args[dtpi->dtpi_pbn - 1]; 313 if (ioctl(fd, DTIOCGARGS, &dtar)) 314 err(1, "DTIOCGARGS"); 315 } 316 317 void 318 dtpi_print_list(int fd) 319 { 320 struct dtioc_probe_info *dtpi; 321 struct dtioc_arg_info *dtai; 322 size_t i, j; 323 324 dtpi = dt_dtpis; 325 for (i = 0; i < dt_ndtpi; i++, dtpi++) { 326 printf("%s:%s:%s", dtpi->dtpi_prov, dtpi_func(dtpi), 327 dtpi->dtpi_name); 328 if (strncmp(dtpi->dtpi_prov, "tracepoint", DTNAMESIZE) == 0) { 329 dtai_cache(fd, dtpi); 330 dtai = dt_args[dtpi->dtpi_pbn - 1]; 331 printf("("); 332 for (j = 0; j < dtpi->dtpi_nargs; j++, dtai++) { 333 if (j > 0) 334 printf(", "); 335 printf("%s", dtai->dtai_argtype); 336 } 337 printf(")"); 338 } 339 printf("\n"); 340 } 341 } 342 343 const char * 344 dtpi_func(struct dtioc_probe_info *dtpi) 345 { 346 char *sysnb, func[DTNAMESIZE]; 347 const char *errstr; 348 int idx; 349 350 if (strncmp(dtpi->dtpi_prov, "syscall", DTNAMESIZE)) 351 return dtpi->dtpi_func; 352 353 /* Translate syscall names */ 354 strlcpy(func, dtpi->dtpi_func, sizeof(func)); 355 sysnb = func; 356 if (strsep(&sysnb, "%") == NULL) 357 return dtpi->dtpi_func; 358 359 idx = strtonum(sysnb, 1, SYS_MAXSYSCALL, &errstr); 360 if (errstr != NULL) 361 return dtpi->dtpi_func; 362 363 return syscallnames[idx]; 364 } 365 366 struct dtioc_probe_info * 367 dtpi_get_by_value(const char *prov, const char *func, const char *name) 368 { 369 struct dtioc_probe_info *dtpi; 370 size_t i; 371 372 dtpi = dt_dtpis; 373 for (i = 0; i < dt_ndtpi; i++, dtpi++) { 374 if (prov != NULL) { 375 if (strncmp(prov, dtpi->dtpi_prov, DTNAMESIZE)) 376 continue; 377 } 378 if (func != NULL && name != NULL) { 379 if (strncmp(func, dtpi_func(dtpi), DTNAMESIZE)) 380 continue; 381 if (strncmp(name, dtpi->dtpi_name, DTNAMESIZE)) 382 continue; 383 } 384 385 debug("matched probe %s:%s:%s\n", dtpi->dtpi_prov, 386 dtpi_func(dtpi), dtpi->dtpi_name); 387 return dtpi; 388 } 389 390 return NULL; 391 } 392 393 static uint64_t 394 bp_nsecs_to_unit(struct bt_probe *bp) 395 { 396 static const struct { 397 const char *name; 398 enum { UNIT_HZ, UNIT_US, UNIT_MS, UNIT_S } id; 399 } units[] = { 400 { .name = "hz", .id = UNIT_HZ }, 401 { .name = "us", .id = UNIT_US }, 402 { .name = "ms", .id = UNIT_MS }, 403 { .name = "s", .id = UNIT_S }, 404 }; 405 size_t i; 406 407 for (i = 0; i < nitems(units); i++) { 408 if (strcmp(units[i].name, bp->bp_unit) == 0) { 409 switch (units[i].id) { 410 case UNIT_HZ: 411 return (1000000000LLU / bp->bp_nsecs); 412 case UNIT_US: 413 return (bp->bp_nsecs / 1000LLU); 414 case UNIT_MS: 415 return (bp->bp_nsecs / 1000000LLU); 416 case UNIT_S: 417 return (bp->bp_nsecs / 1000000000LLU); 418 } 419 } 420 } 421 return 0; 422 } 423 424 void 425 probe_bail(struct bt_probe *bp) 426 { 427 errx(1, "Cannot register multiple probes of the same type: '%s'", 428 probe_name(bp)); 429 } 430 431 const char * 432 probe_name(struct bt_probe *bp) 433 { 434 static char buf[64]; 435 436 if (bp->bp_type == B_PT_BEGIN) 437 return "BEGIN"; 438 439 if (bp->bp_type == B_PT_END) 440 return "END"; 441 442 assert(bp->bp_type == B_PT_PROBE); 443 444 if (bp->bp_nsecs) { 445 snprintf(buf, sizeof(buf), "%s:%s:%llu", bp->bp_prov, 446 bp->bp_unit, bp_nsecs_to_unit(bp)); 447 } else { 448 snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov, 449 bp->bp_unit, bp->bp_name); 450 } 451 452 return buf; 453 } 454 455 void 456 rules_do(int fd) 457 { 458 struct sigaction sa; 459 int halt = 0; 460 461 memset(&sa, 0, sizeof(sa)); 462 sigemptyset(&sa.sa_mask); 463 sa.sa_flags = 0; 464 sa.sa_handler = signal_handler; 465 if (sigaction(SIGINT, &sa, NULL)) 466 err(1, "sigaction"); 467 if (sigaction(SIGTERM, &sa, NULL)) 468 err(1, "sigaction"); 469 470 halt = rules_setup(fd); 471 472 while (!quit_pending && !halt && g_nprobes > 0) { 473 static struct dt_evt devtbuf[64]; 474 ssize_t rlen; 475 size_t i; 476 477 rlen = read(fd, devtbuf, sizeof(devtbuf)); 478 if (rlen == -1) { 479 if (errno == EINTR && quit_pending) { 480 printf("\n"); 481 break; 482 } 483 err(1, "read"); 484 } 485 486 if ((rlen % sizeof(struct dt_evt)) != 0) 487 err(1, "incorrect read"); 488 489 for (i = 0; i < rlen / sizeof(struct dt_evt); i++) { 490 halt = rules_apply(fd, &devtbuf[i]); 491 if (halt) 492 break; 493 } 494 } 495 496 rules_teardown(fd); 497 498 if (verbose && fd != -1) { 499 struct dtioc_stat dtst; 500 501 memset(&dtst, 0, sizeof(dtst)); 502 if (ioctl(fd, DTIOCGSTATS, &dtst)) 503 warn("DTIOCGSTATS"); 504 505 fprintf(stderr, "%llu events read\n", dtst.dtst_readevt); 506 fprintf(stderr, "%llu events dropped\n", dtst.dtst_dropevt); 507 fprintf(stderr, "%llu events filtered\n", bt_filtered); 508 fprintf(stderr, "%llu clock ticks skipped\n", 509 dtst.dtst_skiptick); 510 fprintf(stderr, "%llu recursive events dropped\n", 511 dtst.dtst_recurevt); 512 } 513 } 514 515 static uint64_t 516 rules_action_scan(struct bt_stmt *bs) 517 { 518 struct bt_arg *ba; 519 struct bt_cond *bc; 520 uint64_t evtflags = 0; 521 522 while (bs != NULL) { 523 SLIST_FOREACH(ba, &bs->bs_args, ba_next) 524 evtflags |= ba2dtflags(ba); 525 526 /* Also check the value for map/hist insertion */ 527 switch (bs->bs_act) { 528 case B_AC_BUCKETIZE: 529 case B_AC_INSERT: 530 ba = (struct bt_arg *)bs->bs_var; 531 evtflags |= ba2dtflags(ba); 532 break; 533 case B_AC_TEST: 534 bc = (struct bt_cond *)bs->bs_var; 535 evtflags |= rules_action_scan(bc->bc_condbs); 536 evtflags |= rules_action_scan(bc->bc_elsebs); 537 break; 538 default: 539 break; 540 } 541 542 bs = SLIST_NEXT(bs, bs_next); 543 } 544 545 return evtflags; 546 } 547 548 int 549 rules_setup(int fd) 550 { 551 struct dtioc_probe_info *dtpi; 552 struct dtioc_req *dtrq; 553 struct bt_rule *r, *rbegin = NULL, *rend = NULL; 554 struct bt_probe *bp; 555 struct bt_stmt *bs; 556 struct bt_arg *ba; 557 int dokstack = 0, halt = 0, on = 1; 558 uint64_t evtflags; 559 560 TAILQ_FOREACH(r, &g_rules, br_next) { 561 evtflags = 0; 562 563 if (r->br_filter != NULL && 564 r->br_filter->bf_condition != NULL) { 565 566 bs = r->br_filter->bf_condition; 567 ba = SLIST_FIRST(&bs->bs_args); 568 569 evtflags |= ba2dtflags(ba); 570 } 571 572 evtflags |= rules_action_scan(SLIST_FIRST(&r->br_action)); 573 574 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 575 debug("parsed probe '%s'", probe_name(bp)); 576 debug_dump_filter(r); 577 578 if (bp->bp_type != B_PT_PROBE) { 579 if (bp->bp_type == B_PT_BEGIN) { 580 if (rbegin != NULL) 581 probe_bail(bp); 582 rbegin = r; 583 } 584 if (bp->bp_type == B_PT_END) { 585 if (rend != NULL) 586 probe_bail(bp); 587 rend = r; 588 } 589 continue; 590 } 591 592 dtpi_cache(fd); 593 dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func, 594 bp->bp_name); 595 if (dtpi == NULL) { 596 errx(1, "probe '%s:%s:%s' not found", 597 bp->bp_prov, bp->bp_func, bp->bp_name); 598 } 599 600 dtrq = calloc(1, sizeof(*dtrq)); 601 if (dtrq == NULL) 602 err(1, "dtrq: 1alloc"); 603 604 bp->bp_pbn = dtpi->dtpi_pbn; 605 dtrq->dtrq_pbn = dtpi->dtpi_pbn; 606 dtrq->dtrq_nsecs = bp->bp_nsecs; 607 dtrq->dtrq_evtflags = evtflags; 608 if (dtrq->dtrq_evtflags & DTEVT_KSTACK) 609 dokstack = 1; 610 bp->bp_cookie = dtrq; 611 } 612 } 613 614 if (dokstack) 615 kelf = kelf_open(_PATH_KSYMS); 616 617 /* Initialize "fake" event for BEGIN/END */ 618 bt_devt.dtev_pbn = EVENT_BEGIN; 619 strlcpy(bt_devt.dtev_comm, getprogname(), sizeof(bt_devt.dtev_comm)); 620 bt_devt.dtev_pid = getpid(); 621 bt_devt.dtev_tid = getthrid(); 622 clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp); 623 624 if (rbegin) 625 halt = rule_eval(rbegin, &bt_devt); 626 627 /* Enable all probes */ 628 TAILQ_FOREACH(r, &g_rules, br_next) { 629 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 630 if (bp->bp_type != B_PT_PROBE) 631 continue; 632 633 dtrq = bp->bp_cookie; 634 if (ioctl(fd, DTIOCPRBENABLE, dtrq)) { 635 if (errno == EEXIST) 636 probe_bail(bp); 637 err(1, "DTIOCPRBENABLE"); 638 } 639 } 640 } 641 642 if (g_nprobes > 0) { 643 if (ioctl(fd, DTIOCRECORD, &on)) 644 err(1, "DTIOCRECORD"); 645 } 646 647 return halt; 648 } 649 650 /* 651 * Returns non-zero if the program should halt. 652 */ 653 int 654 rules_apply(int fd, struct dt_evt *dtev) 655 { 656 struct bt_rule *r; 657 struct bt_probe *bp; 658 659 TAILQ_FOREACH(r, &g_rules, br_next) { 660 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 661 if (bp->bp_type != B_PT_PROBE || 662 bp->bp_pbn != dtev->dtev_pbn) 663 continue; 664 665 dtai_cache(fd, &dt_dtpis[dtev->dtev_pbn - 1]); 666 if (rule_eval(r, dtev)) 667 return 1; 668 } 669 } 670 return 0; 671 } 672 673 void 674 rules_teardown(int fd) 675 { 676 struct dtioc_req *dtrq; 677 struct bt_probe *bp; 678 struct bt_rule *r, *rend = NULL; 679 int dokstack = 0, off = 0; 680 681 if (g_nprobes > 0) { 682 if (ioctl(fd, DTIOCRECORD, &off)) 683 err(1, "DTIOCRECORD"); 684 } 685 686 TAILQ_FOREACH(r, &g_rules, br_next) { 687 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 688 if (bp->bp_type != B_PT_PROBE) { 689 if (bp->bp_type == B_PT_END) 690 rend = r; 691 continue; 692 } 693 694 dtrq = bp->bp_cookie; 695 if (ioctl(fd, DTIOCPRBDISABLE, dtrq)) 696 err(1, "DTIOCPRBDISABLE"); 697 if (dtrq->dtrq_evtflags & DTEVT_KSTACK) 698 dokstack = 1; 699 } 700 } 701 702 kelf_close(kelf); 703 kelf = NULL; 704 kelf_close(uelf); 705 uelf = NULL; 706 707 /* Update "fake" event for BEGIN/END */ 708 bt_devt.dtev_pbn = EVENT_END; 709 clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp); 710 711 if (rend) 712 rule_eval(rend, &bt_devt); 713 714 /* Print non-empty map & hist */ 715 TAILQ_FOREACH(r, &g_rules, br_next) 716 rule_printmaps(r); 717 } 718 719 /* 720 * Returns non-zero if the program should halt. 721 */ 722 int 723 rule_eval(struct bt_rule *r, struct dt_evt *dtev) 724 { 725 struct bt_stmt *bs; 726 struct bt_probe *bp; 727 728 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 729 debug("eval rule '%s'", probe_name(bp)); 730 debug_dump_filter(r); 731 } 732 733 if (r->br_filter != NULL && r->br_filter->bf_condition != NULL) { 734 if (stmt_test(r->br_filter->bf_condition, dtev) == false) { 735 bt_filtered++; 736 return 0; 737 } 738 } 739 740 SLIST_FOREACH(bs, &r->br_action, bs_next) { 741 if (stmt_eval(bs, dtev)) 742 return 1; 743 } 744 745 return 0; 746 } 747 748 void 749 rule_printmaps(struct bt_rule *r) 750 { 751 struct bt_stmt *bs; 752 753 SLIST_FOREACH(bs, &r->br_action, bs_next) { 754 struct bt_arg *ba; 755 756 SLIST_FOREACH(ba, &bs->bs_args, ba_next) { 757 struct bt_var *bv = ba->ba_value; 758 struct map *map; 759 760 if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST) 761 continue; 762 763 map = (struct map *)bv->bv_value; 764 if (map == NULL) 765 continue; 766 767 if (ba->ba_type == B_AT_MAP) 768 map_print(map, SIZE_T_MAX, bv_name(bv)); 769 else 770 hist_print((struct hist *)map, bv_name(bv)); 771 map_clear(map); 772 bv->bv_value = NULL; 773 } 774 } 775 } 776 777 time_t 778 builtin_gettime(struct dt_evt *dtev) 779 { 780 struct timespec ts; 781 782 if (dtev == NULL) { 783 clock_gettime(CLOCK_REALTIME, &ts); 784 return ts.tv_sec; 785 } 786 787 return dtev->dtev_tsp.tv_sec; 788 } 789 790 static inline uint64_t 791 TIMESPEC_TO_NSEC(struct timespec *ts) 792 { 793 return (ts->tv_sec * 1000000000L + ts->tv_nsec); 794 } 795 796 uint64_t 797 builtin_nsecs(struct dt_evt *dtev) 798 { 799 struct timespec ts; 800 801 if (dtev == NULL) { 802 clock_gettime(CLOCK_REALTIME, &ts); 803 return TIMESPEC_TO_NSEC(&ts); 804 } 805 806 return TIMESPEC_TO_NSEC(&dtev->dtev_tsp); 807 } 808 809 const char * 810 builtin_stack(struct dt_evt *dtev, int kernel, unsigned long offset) 811 { 812 struct stacktrace *st = &dtev->dtev_kstack; 813 static char buf[4096]; 814 const char *last = "\nkernel\n"; 815 char *bp; 816 size_t i; 817 int sz; 818 819 if (!kernel) { 820 st = &dtev->dtev_ustack; 821 last = "\nuserland\n"; 822 } else if (st->st_count == 0) { 823 return "\nuserland\n"; 824 } 825 826 buf[0] = '\0'; 827 bp = buf; 828 sz = sizeof(buf); 829 for (i = 0; i < st->st_count; i++) { 830 int l; 831 832 if (!kernel) 833 l = kelf_snprintsym(uelf, bp, sz - 1, st->st_pc[i], 834 offset); 835 else 836 l = kelf_snprintsym(kelf, bp, sz - 1, st->st_pc[i], 837 offset); 838 if (l < 0) 839 break; 840 if (l >= sz - 1) { 841 bp += sz - 1; 842 sz = 1; 843 break; 844 } 845 bp += l; 846 sz -= l; 847 } 848 snprintf(bp, sz, "%s", last); 849 850 return buf; 851 } 852 853 const char * 854 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat) 855 { 856 static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */ 857 struct dtioc_probe_info *dtpi; 858 struct dtioc_arg_info *dtai; 859 const char *argtype, *fmt; 860 unsigned int argn; 861 long value; 862 863 argn = dat - B_AT_BI_ARG0; 864 dtpi = &dt_dtpis[dtev->dtev_pbn - 1]; 865 if (dtpi == NULL || argn >= dtpi->dtpi_nargs) 866 return "0"; 867 868 dtai = dt_args[dtev->dtev_pbn - 1]; 869 argtype = dtai[argn].dtai_argtype; 870 871 if (strncmp(argtype, "int", DTNAMESIZE) == 0) { 872 fmt = "%d"; 873 value = (int)dtev->dtev_args[argn]; 874 } else { 875 fmt = "%lu"; 876 value = dtev->dtev_args[argn]; 877 } 878 879 snprintf(buf, sizeof(buf), fmt, dtev->dtev_args[argn]); 880 881 return buf; 882 } 883 884 /* 885 * Returns non-zero if the program should halt. 886 */ 887 int 888 stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev) 889 { 890 struct bt_stmt *bbs; 891 struct bt_cond *bc; 892 int halt = 0; 893 894 switch (bs->bs_act) { 895 case B_AC_BUCKETIZE: 896 stmt_bucketize(bs, dtev); 897 break; 898 case B_AC_CLEAR: 899 stmt_clear(bs); 900 break; 901 case B_AC_DELETE: 902 stmt_delete(bs, dtev); 903 break; 904 case B_AC_EXIT: 905 halt = 1; 906 break; 907 case B_AC_INSERT: 908 stmt_insert(bs, dtev); 909 break; 910 case B_AC_PRINT: 911 stmt_print(bs, dtev); 912 break; 913 case B_AC_PRINTF: 914 stmt_printf(bs, dtev); 915 break; 916 case B_AC_STORE: 917 stmt_store(bs, dtev); 918 break; 919 case B_AC_TEST: 920 bc = (struct bt_cond *)bs->bs_var; 921 if (stmt_test(bs, dtev) == true) 922 bbs = bc->bc_condbs; 923 else 924 bbs = bc->bc_elsebs; 925 926 while (bbs != NULL) { 927 if (stmt_eval(bbs, dtev)) 928 return 1; 929 bbs = SLIST_NEXT(bbs, bs_next); 930 } 931 break; 932 case B_AC_TIME: 933 stmt_time(bs, dtev); 934 break; 935 case B_AC_ZERO: 936 stmt_zero(bs); 937 break; 938 default: 939 xabort("no handler for action type %d", bs->bs_act); 940 } 941 return halt; 942 } 943 944 /* 945 * Increment a bucket: { @h = hist(v); } or { @h = lhist(v, min, max, step); } 946 * 947 * In this case 'h' is represented by `bv' and '(min, max, step)' by `brange'. 948 */ 949 void 950 stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev) 951 { 952 struct bt_arg *brange, *bhist = SLIST_FIRST(&bs->bs_args); 953 struct bt_arg *bval = (struct bt_arg *)bs->bs_var; 954 struct bt_var *bv = bhist->ba_value; 955 struct hist *hist; 956 const char *bucket; 957 long step = 0; 958 959 assert(bhist->ba_type == B_AT_HIST); 960 assert(SLIST_NEXT(bval, ba_next) == NULL); 961 962 brange = bhist->ba_key; 963 bucket = ba2bucket(bval, brange, dtev, &step); 964 if (bucket == NULL) { 965 debug("hist=%p '%s' value=%lu out of range\n", bv->bv_value, 966 bv_name(bv), ba2long(bval, dtev)); 967 return; 968 } 969 debug("hist=%p '%s' increment bucket '%s'\n", bv->bv_value, 970 bv_name(bv), bucket); 971 972 /* hist is NULL before first insert or after clear() */ 973 hist = (struct hist *)bv->bv_value; 974 if (hist == NULL) 975 hist = hist_new(step); 976 977 hist_increment(hist, bucket); 978 979 debug("hist=%p '%s' increment bucket=%p '%s' bval=%p\n", hist, 980 bv_name(bv), brange, bucket, bval); 981 982 bv->bv_value = (struct bt_arg *)hist; 983 bv->bv_type = B_VT_HIST; 984 } 985 986 987 /* 988 * Empty a map: { clear(@map); } 989 */ 990 void 991 stmt_clear(struct bt_stmt *bs) 992 { 993 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 994 struct bt_var *bv = ba->ba_value; 995 struct map *map; 996 997 assert(bs->bs_var == NULL); 998 assert(ba->ba_type == B_AT_VAR); 999 1000 map = (struct map *)bv->bv_value; 1001 if (map == NULL) 1002 return; 1003 1004 if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST) 1005 errx(1, "invalid variable type for clear(%s)", ba_name(ba)); 1006 1007 map_clear(map); 1008 bv->bv_value = NULL; 1009 1010 debug("map=%p '%s' clear\n", map, bv_name(bv)); 1011 } 1012 1013 /* 1014 * Map delete: { delete(@map[key]); } 1015 * 1016 * In this case 'map' is represented by `bv' and 'key' by `bkey'. 1017 */ 1018 void 1019 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev) 1020 { 1021 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 1022 struct bt_var *bv = bmap->ba_value; 1023 struct map *map; 1024 const char *hash; 1025 1026 assert(bmap->ba_type == B_AT_MAP); 1027 assert(bs->bs_var == NULL); 1028 1029 map = (struct map *)bv->bv_value; 1030 if (map == NULL) 1031 return; 1032 1033 bkey = bmap->ba_key; 1034 hash = ba2hash(bkey, dtev); 1035 debug("map=%p '%s' delete key=%p '%s'\n", map, bv_name(bv), bkey, hash); 1036 1037 map_delete(map, hash); 1038 } 1039 1040 /* 1041 * Map insert: { @map[key] = 42; } 1042 * 1043 * In this case 'map' is represented by `bv', 'key' by `bkey' and 1044 * '42' by `bval'. 1045 */ 1046 void 1047 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev) 1048 { 1049 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 1050 struct bt_arg *bval = (struct bt_arg *)bs->bs_var; 1051 struct bt_var *bv = bmap->ba_value; 1052 struct map *map; 1053 const char *hash; 1054 long val; 1055 1056 assert(bmap->ba_type == B_AT_MAP); 1057 assert(SLIST_NEXT(bval, ba_next) == NULL); 1058 1059 bkey = bmap->ba_key; 1060 hash = ba2hash(bkey, dtev); 1061 1062 /* map is NULL before first insert or after clear() */ 1063 map = (struct map *)bv->bv_value; 1064 if (map == NULL) 1065 map = map_new(); 1066 1067 /* Operate on existring value for count(), max(), min() and sum(). */ 1068 switch (bval->ba_type) { 1069 case B_AT_MF_COUNT: 1070 val = ba2long(map_get(map, hash), NULL); 1071 val++; 1072 bval = ba_new(val, B_AT_LONG); 1073 break; 1074 case B_AT_MF_MAX: 1075 val = ba2long(map_get(map, hash), NULL); 1076 val = MAXIMUM(val, ba2long(bval->ba_value, dtev)); 1077 bval = ba_new(val, B_AT_LONG); 1078 break; 1079 case B_AT_MF_MIN: 1080 val = ba2long(map_get(map, hash), NULL); 1081 val = MINIMUM(val, ba2long(bval->ba_value, dtev)); 1082 bval = ba_new(val, B_AT_LONG); 1083 break; 1084 case B_AT_MF_SUM: 1085 val = ba2long(map_get(map, hash), NULL); 1086 val += ba2long(bval->ba_value, dtev); 1087 bval = ba_new(val, B_AT_LONG); 1088 break; 1089 default: 1090 bval = baeval(bval, dtev); 1091 break; 1092 } 1093 1094 map_insert(map, hash, bval); 1095 1096 debug("map=%p '%s' insert key=%p '%s' bval=%p\n", map, 1097 bv_name(bv), bkey, hash, bval); 1098 1099 bv->bv_value = (struct bt_arg *)map; 1100 bv->bv_type = B_VT_MAP; 1101 } 1102 1103 /* 1104 * Print variables: { print(890); print(@map[, 8]); print(comm); } 1105 * 1106 * In this case the global variable 'map' is pointed at by `ba' 1107 * and '8' is represented by `btop'. 1108 */ 1109 void 1110 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev) 1111 { 1112 struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args); 1113 struct bt_var *bv = ba->ba_value; 1114 struct map *map; 1115 size_t top = SIZE_T_MAX; 1116 1117 assert(bs->bs_var == NULL); 1118 1119 /* Parse optional `top' argument. */ 1120 btop = SLIST_NEXT(ba, ba_next); 1121 if (btop != NULL) { 1122 assert(SLIST_NEXT(btop, ba_next) == NULL); 1123 top = ba2long(btop, dtev); 1124 } 1125 1126 /* Static argument. */ 1127 if (ba->ba_type != B_AT_VAR) { 1128 assert(btop == NULL); 1129 printf("%s\n", ba2str(ba, dtev)); 1130 return; 1131 } 1132 1133 map = (struct map *)bv->bv_value; 1134 if (map == NULL) 1135 return; 1136 1137 debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top); 1138 1139 if (bv->bv_type == B_VT_MAP) 1140 map_print(map, top, bv_name(bv)); 1141 else if (bv->bv_type == B_VT_HIST) 1142 hist_print((struct hist *)map, bv_name(bv)); 1143 else 1144 printf("%s\n", ba2str(ba, dtev)); 1145 } 1146 1147 /* 1148 * Variable store: { @var = 3; } 1149 * 1150 * In this case '3' is represented by `ba', the argument of a STORE 1151 * action. 1152 * 1153 * If the argument depends of the value of an event (builtin) or is 1154 * the result of an operation, its evaluation is stored in a new `ba'. 1155 */ 1156 void 1157 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev) 1158 { 1159 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 1160 struct bt_var *bvar, *bv = bs->bs_var; 1161 struct map *map; 1162 1163 assert(SLIST_NEXT(ba, ba_next) == NULL); 1164 1165 switch (ba->ba_type) { 1166 case B_AT_STR: 1167 bv->bv_value = ba; 1168 bv->bv_type = B_VT_STR; 1169 break; 1170 case B_AT_LONG: 1171 bv->bv_value = ba; 1172 bv->bv_type = B_VT_LONG; 1173 break; 1174 case B_AT_VAR: 1175 bvar = ba->ba_value; 1176 bv->bv_type = bvar->bv_type; 1177 bv->bv_value = bvar->bv_value; 1178 break; 1179 case B_AT_MAP: 1180 bvar = ba->ba_value; 1181 map = (struct map *)bvar->bv_value; 1182 /* Uninitialized map */ 1183 if (map == NULL) 1184 bv->bv_value = 0; 1185 else 1186 bv->bv_value = map_get(map, ba2hash(ba->ba_key, dtev)); 1187 bv->bv_type = B_VT_LONG; /* XXX should we type map? */ 1188 break; 1189 case B_AT_TUPLE: 1190 bv->bv_value = baeval(ba, dtev); 1191 bv->bv_type = B_VT_TUPLE; 1192 break; 1193 case B_AT_BI_PID: 1194 case B_AT_BI_TID: 1195 case B_AT_BI_CPU: 1196 case B_AT_BI_NSECS: 1197 case B_AT_BI_RETVAL: 1198 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1199 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1200 bv->bv_value = baeval(ba, dtev); 1201 bv->bv_type = B_VT_LONG; 1202 break; 1203 case B_AT_BI_COMM: 1204 case B_AT_BI_KSTACK: 1205 case B_AT_BI_USTACK: 1206 case B_AT_BI_PROBE: 1207 case B_AT_FN_STR: 1208 bv->bv_value = baeval(ba, dtev); 1209 bv->bv_type = B_VT_STR; 1210 break; 1211 default: 1212 xabort("store not implemented for type %d", ba->ba_type); 1213 } 1214 1215 debug("bv=%p var '%s' store (%p)='%s'\n", bv, bv_name(bv), bv->bv_value, 1216 ba2str(bv->bv_value, dtev)); 1217 } 1218 1219 /* 1220 * String conversion { str($1); string($1, 3); } 1221 * 1222 * Since fn_str is currently only called in ba2str, *buf should be a pointer 1223 * to the static buffer provided by ba2str. 1224 */ 1225 struct bt_arg * 1226 fn_str(struct bt_arg *ba, struct dt_evt *dtev, char *buf) 1227 { 1228 struct bt_arg *arg, *index; 1229 ssize_t len = STRLEN; 1230 1231 assert(ba->ba_type == B_AT_FN_STR); 1232 1233 arg = (struct bt_arg*)ba->ba_value; 1234 assert(arg != NULL); 1235 1236 index = SLIST_NEXT(arg, ba_next); 1237 if (index != NULL) { 1238 /* Should have only 1 optional argument. */ 1239 assert(SLIST_NEXT(index, ba_next) == NULL); 1240 len = MINIMUM(ba2long(index, dtev) + 1, STRLEN); 1241 } 1242 1243 /* All negative lengths behave the same as a zero length. */ 1244 if (len < 1) 1245 return ba_new("", B_AT_STR); 1246 1247 strlcpy(buf, ba2str(arg, dtev), len); 1248 return ba_new(buf, B_AT_STR); 1249 } 1250 1251 /* 1252 * Expression test: { if (expr) stmt; } 1253 */ 1254 bool 1255 stmt_test(struct bt_stmt *bs, struct dt_evt *dtev) 1256 { 1257 struct bt_arg *ba; 1258 1259 if (bs == NULL) 1260 return true; 1261 1262 ba = SLIST_FIRST(&bs->bs_args); 1263 1264 return baexpr2long(ba, dtev) != 0; 1265 } 1266 1267 /* 1268 * Print time: { time("%H:%M:%S"); } 1269 */ 1270 void 1271 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev) 1272 { 1273 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 1274 time_t time; 1275 struct tm *tm; 1276 char buf[64]; 1277 1278 assert(bs->bs_var == NULL); 1279 assert(ba->ba_type == B_AT_STR); 1280 assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1)); 1281 1282 time = builtin_gettime(dtev); 1283 tm = localtime(&time); 1284 strftime(buf, sizeof(buf), ba2str(ba, dtev), tm); 1285 printf("%s", buf); 1286 } 1287 1288 /* 1289 * Set entries to 0: { zero(@map); } 1290 */ 1291 void 1292 stmt_zero(struct bt_stmt *bs) 1293 { 1294 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 1295 struct bt_var *bv = ba->ba_value; 1296 struct map *map; 1297 1298 assert(bs->bs_var == NULL); 1299 assert(ba->ba_type == B_AT_VAR); 1300 1301 map = (struct map *)bv->bv_value; 1302 if (map == NULL) 1303 return; 1304 1305 if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST) 1306 errx(1, "invalid variable type for zero(%s)", ba_name(ba)); 1307 1308 map_zero(map); 1309 1310 debug("map=%p '%s' zero\n", map, bv_name(bv)); 1311 } 1312 1313 struct bt_arg * 1314 ba_read(struct bt_arg *ba) 1315 { 1316 struct bt_var *bv = ba->ba_value; 1317 1318 assert(ba->ba_type == B_AT_VAR); 1319 debug("bv=%p read '%s' (%p)\n", bv, bv_name(bv), bv->bv_value); 1320 1321 /* Handle map/hist access after clear(). */ 1322 if (bv->bv_value == NULL) 1323 return &g_nullba; 1324 1325 return bv->bv_value; 1326 } 1327 1328 // XXX 1329 extern struct bt_arg *ba_append(struct bt_arg *, struct bt_arg *); 1330 1331 /* 1332 * Return a new argument that doesn't depend on `dtev'. This is used 1333 * when storing values in variables, maps, etc. 1334 */ 1335 struct bt_arg * 1336 baeval(struct bt_arg *bval, struct dt_evt *dtev) 1337 { 1338 struct bt_arg *ba, *bh = NULL; 1339 1340 switch (bval->ba_type) { 1341 case B_AT_VAR: 1342 ba = baeval(ba_read(bval), NULL); 1343 break; 1344 case B_AT_LONG: 1345 case B_AT_BI_PID: 1346 case B_AT_BI_TID: 1347 case B_AT_BI_CPU: 1348 case B_AT_BI_NSECS: 1349 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1350 case B_AT_BI_RETVAL: 1351 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1352 ba = ba_new(ba2long(bval, dtev), B_AT_LONG); 1353 break; 1354 case B_AT_STR: 1355 case B_AT_BI_COMM: 1356 case B_AT_BI_KSTACK: 1357 case B_AT_BI_USTACK: 1358 case B_AT_BI_PROBE: 1359 case B_AT_FN_STR: 1360 ba = ba_new(ba2str(bval, dtev), B_AT_STR); 1361 break; 1362 case B_AT_TUPLE: 1363 ba = bval->ba_value; 1364 do { 1365 bh = ba_append(bh, baeval(ba, dtev)); 1366 } while ((ba = SLIST_NEXT(ba, ba_next)) != NULL); 1367 ba = ba_new(bh, B_AT_TUPLE); 1368 break; 1369 default: 1370 xabort("no eval support for type %d", bval->ba_type); 1371 } 1372 1373 return ba; 1374 } 1375 1376 /* 1377 * Return a string of coma-separated values 1378 */ 1379 const char * 1380 ba2hash(struct bt_arg *ba, struct dt_evt *dtev) 1381 { 1382 static char buf[KLEN]; 1383 char *hash; 1384 int l, len; 1385 1386 buf[0] = '\0'; 1387 l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev)); 1388 if (l < 0 || (size_t)l > sizeof(buf)) { 1389 warn("string too long %d > %lu", l, sizeof(buf)); 1390 return buf; 1391 } 1392 1393 len = 0; 1394 while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) { 1395 len += l; 1396 hash = buf + len; 1397 1398 l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev)); 1399 if (l < 0 || (size_t)l > (sizeof(buf) - len)) { 1400 warn("hash too long %d > %lu", l + len, sizeof(buf)); 1401 break; 1402 } 1403 } 1404 1405 return buf; 1406 } 1407 1408 static unsigned long 1409 next_pow2(unsigned long x) 1410 { 1411 size_t i; 1412 1413 x--; 1414 for (i = 0; i < (sizeof(x) * 8) - 1; i++) 1415 x |= (x >> 1); 1416 1417 return x + 1; 1418 } 1419 1420 /* 1421 * Return the ceiling value the interval holding `ba' or NULL if it is 1422 * out of the (min, max) values. 1423 */ 1424 const char * 1425 ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev, 1426 long *pstep) 1427 { 1428 static char buf[KLEN]; 1429 long val, bucket; 1430 int l; 1431 1432 val = ba2long(ba, dtev); 1433 if (brange == NULL) 1434 bucket = next_pow2(val); 1435 else { 1436 long min, max, step; 1437 1438 assert(brange->ba_type == B_AT_LONG); 1439 min = ba2long(brange, NULL); 1440 1441 brange = SLIST_NEXT(brange, ba_next); 1442 assert(brange->ba_type == B_AT_LONG); 1443 max = ba2long(brange, NULL); 1444 1445 if ((val < min) || (val > max)) 1446 return NULL; 1447 1448 brange = SLIST_NEXT(brange, ba_next); 1449 assert(brange->ba_type == B_AT_LONG); 1450 step = ba2long(brange, NULL); 1451 1452 bucket = ((val / step) + 1) * step; 1453 *pstep = step; 1454 } 1455 1456 buf[0] = '\0'; 1457 l = snprintf(buf, sizeof(buf), "%lu", bucket); 1458 if (l < 0 || (size_t)l > sizeof(buf)) { 1459 warn("string too long %d > %lu", l, sizeof(buf)); 1460 return buf; 1461 } 1462 1463 return buf; 1464 } 1465 1466 /* 1467 * Evaluate the operation encoded in `ba' and return its result. 1468 */ 1469 long 1470 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev) 1471 { 1472 static long recursions; 1473 struct bt_arg *lhs, *rhs; 1474 long lval, rval, result; 1475 1476 if (++recursions >= __MAXOPERANDS) 1477 errx(1, "too many operands (>%d) in expression", __MAXOPERANDS); 1478 1479 lhs = ba->ba_value; 1480 rhs = SLIST_NEXT(lhs, ba_next); 1481 1482 /* 1483 * String comparison also use '==' and '!='. 1484 */ 1485 if (lhs->ba_type == B_AT_STR || 1486 (rhs != NULL && rhs->ba_type == B_AT_STR)) { 1487 char lstr[STRLEN], rstr[STRLEN]; 1488 1489 strlcpy(lstr, ba2str(lhs, dtev), sizeof(lstr)); 1490 strlcpy(rstr, ba2str(rhs, dtev), sizeof(rstr)); 1491 1492 result = strncmp(lstr, rstr, STRLEN) == 0; 1493 1494 switch (ba->ba_type) { 1495 case B_AT_OP_EQ: 1496 break; 1497 case B_AT_OP_NE: 1498 result = !result; 1499 break; 1500 default: 1501 warnx("operation '%d' unsupported on strings", 1502 ba->ba_type); 1503 result = 1; 1504 } 1505 1506 debug("ba=%p eval '(%s %s %s) = %d'\n", ba, lstr, ba_name(ba), 1507 rstr, result); 1508 1509 goto out; 1510 } 1511 1512 lval = ba2long(lhs, dtev); 1513 if (rhs == NULL) { 1514 rval = 0; 1515 } else { 1516 assert(SLIST_NEXT(rhs, ba_next) == NULL); 1517 rval = ba2long(rhs, dtev); 1518 } 1519 1520 switch (ba->ba_type) { 1521 case B_AT_OP_PLUS: 1522 result = lval + rval; 1523 break; 1524 case B_AT_OP_MINUS: 1525 result = lval - rval; 1526 break; 1527 case B_AT_OP_MULT: 1528 result = lval * rval; 1529 break; 1530 case B_AT_OP_DIVIDE: 1531 result = lval / rval; 1532 break; 1533 case B_AT_OP_MODULO: 1534 result = lval % rval; 1535 break; 1536 case B_AT_OP_BAND: 1537 result = lval & rval; 1538 break; 1539 case B_AT_OP_XOR: 1540 result = lval ^ rval; 1541 break; 1542 case B_AT_OP_BOR: 1543 result = lval | rval; 1544 break; 1545 case B_AT_OP_EQ: 1546 result = (lval == rval); 1547 break; 1548 case B_AT_OP_NE: 1549 result = (lval != rval); 1550 break; 1551 case B_AT_OP_LE: 1552 result = (lval <= rval); 1553 break; 1554 case B_AT_OP_LT: 1555 result = (lval < rval); 1556 break; 1557 case B_AT_OP_GE: 1558 result = (lval >= rval); 1559 break; 1560 case B_AT_OP_GT: 1561 result = (lval > rval); 1562 break; 1563 case B_AT_OP_LAND: 1564 result = (lval && rval); 1565 break; 1566 case B_AT_OP_LOR: 1567 result = (lval || rval); 1568 break; 1569 default: 1570 xabort("unsupported operation %d", ba->ba_type); 1571 } 1572 1573 debug("ba=%p eval '(%ld %s %ld) = %d'\n", ba, lval, ba_name(ba), 1574 rval, result); 1575 1576 out: 1577 --recursions; 1578 1579 return result; 1580 } 1581 1582 const char * 1583 ba_name(struct bt_arg *ba) 1584 { 1585 switch (ba->ba_type) { 1586 case B_AT_STR: 1587 return (const char *)ba->ba_value; 1588 case B_AT_LONG: 1589 return ba2str(ba, NULL); 1590 case B_AT_NIL: 1591 return "0"; 1592 case B_AT_VAR: 1593 case B_AT_MAP: 1594 case B_AT_HIST: 1595 break; 1596 case B_AT_BI_PID: 1597 return "pid"; 1598 case B_AT_BI_TID: 1599 return "tid"; 1600 case B_AT_BI_COMM: 1601 return "comm"; 1602 case B_AT_BI_CPU: 1603 return "cpu"; 1604 case B_AT_BI_NSECS: 1605 return "nsecs"; 1606 case B_AT_BI_KSTACK: 1607 return "kstack"; 1608 case B_AT_BI_USTACK: 1609 return "ustack"; 1610 case B_AT_BI_ARG0: 1611 return "arg0"; 1612 case B_AT_BI_ARG1: 1613 return "arg1"; 1614 case B_AT_BI_ARG2: 1615 return "arg2"; 1616 case B_AT_BI_ARG3: 1617 return "arg3"; 1618 case B_AT_BI_ARG4: 1619 return "arg4"; 1620 case B_AT_BI_ARG5: 1621 return "arg5"; 1622 case B_AT_BI_ARG6: 1623 return "arg6"; 1624 case B_AT_BI_ARG7: 1625 return "arg7"; 1626 case B_AT_BI_ARG8: 1627 return "arg8"; 1628 case B_AT_BI_ARG9: 1629 return "arg9"; 1630 case B_AT_BI_ARGS: 1631 return "args"; 1632 case B_AT_BI_RETVAL: 1633 return "retval"; 1634 case B_AT_BI_PROBE: 1635 return "probe"; 1636 case B_AT_FN_STR: 1637 return "str"; 1638 case B_AT_OP_PLUS: 1639 return "+"; 1640 case B_AT_OP_MINUS: 1641 return "-"; 1642 case B_AT_OP_MULT: 1643 return "*"; 1644 case B_AT_OP_DIVIDE: 1645 return "/"; 1646 case B_AT_OP_MODULO: 1647 return "%"; 1648 case B_AT_OP_BAND: 1649 return "&"; 1650 case B_AT_OP_XOR: 1651 return "^"; 1652 case B_AT_OP_BOR: 1653 return "|"; 1654 case B_AT_OP_EQ: 1655 return "=="; 1656 case B_AT_OP_NE: 1657 return "!="; 1658 case B_AT_OP_LE: 1659 return "<="; 1660 case B_AT_OP_LT: 1661 return "<"; 1662 case B_AT_OP_GE: 1663 return ">="; 1664 case B_AT_OP_GT: 1665 return ">"; 1666 case B_AT_OP_LAND: 1667 return "&&"; 1668 case B_AT_OP_LOR: 1669 return "||"; 1670 default: 1671 xabort("unsupported type %d", ba->ba_type); 1672 } 1673 1674 assert(ba->ba_type == B_AT_VAR || ba->ba_type == B_AT_MAP || 1675 ba->ba_type == B_AT_HIST); 1676 1677 static char buf[64]; 1678 size_t sz; 1679 int l; 1680 1681 buf[0] = '@'; 1682 buf[1] = '\0'; 1683 sz = sizeof(buf) - 1; 1684 l = snprintf(buf+1, sz, "%s", bv_name(ba->ba_value)); 1685 if (l < 0 || (size_t)l > sz) { 1686 warn("string too long %d > %zu", l, sz); 1687 return buf; 1688 } 1689 1690 if (ba->ba_type == B_AT_MAP) { 1691 sz -= l; 1692 l = snprintf(buf+1+l, sz, "[%s]", ba_name(ba->ba_key)); 1693 if (l < 0 || (size_t)l > sz) { 1694 warn("string too long %d > %zu", l, sz); 1695 return buf; 1696 } 1697 } 1698 1699 return buf; 1700 } 1701 1702 /* 1703 * Return the representation of `ba' as long. 1704 */ 1705 long 1706 ba2long(struct bt_arg *ba, struct dt_evt *dtev) 1707 { 1708 struct bt_var *bv; 1709 long val; 1710 1711 switch (ba->ba_type) { 1712 case B_AT_STR: 1713 val = (*ba2str(ba, dtev) == '\0') ? 0 : 1; 1714 break; 1715 case B_AT_LONG: 1716 val = (long)ba->ba_value; 1717 break; 1718 case B_AT_VAR: 1719 ba = ba_read(ba); 1720 val = (long)ba->ba_value; 1721 break; 1722 case B_AT_MAP: 1723 bv = ba->ba_value; 1724 /* Uninitialized map */ 1725 if (bv->bv_value == NULL) 1726 return 0; 1727 val = ba2long(map_get((struct map *)bv->bv_value, 1728 ba2hash(ba->ba_key, dtev)), dtev); 1729 break; 1730 case B_AT_NIL: 1731 val = 0L; 1732 break; 1733 case B_AT_BI_PID: 1734 val = dtev->dtev_pid; 1735 break; 1736 case B_AT_BI_TID: 1737 val = dtev->dtev_tid; 1738 break; 1739 case B_AT_BI_CPU: 1740 val = dtev->dtev_cpu; 1741 break; 1742 case B_AT_BI_NSECS: 1743 val = builtin_nsecs(dtev); 1744 break; 1745 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1746 val = dtev->dtev_args[ba->ba_type - B_AT_BI_ARG0]; 1747 break; 1748 case B_AT_BI_RETVAL: 1749 val = dtev->dtev_retval[0]; 1750 break; 1751 case B_AT_BI_PROBE: 1752 val = dtev->dtev_pbn; 1753 break; 1754 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1755 val = baexpr2long(ba, dtev); 1756 break; 1757 default: 1758 xabort("no long conversion for type %d", ba->ba_type); 1759 } 1760 1761 return val; 1762 } 1763 1764 /* 1765 * Return the representation of `ba' as string. 1766 */ 1767 const char * 1768 ba2str(struct bt_arg *ba, struct dt_evt *dtev) 1769 { 1770 static char buf[STRLEN]; 1771 struct bt_var *bv; 1772 struct dtioc_probe_info *dtpi; 1773 unsigned long idx; 1774 const char *str; 1775 1776 buf[0] = '\0'; 1777 switch (ba->ba_type) { 1778 case B_AT_STR: 1779 str = (const char *)ba->ba_value; 1780 break; 1781 case B_AT_LONG: 1782 snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value); 1783 str = buf; 1784 break; 1785 case B_AT_TUPLE: 1786 snprintf(buf, sizeof(buf), "(%s)", ba2hash(ba->ba_value, dtev)); 1787 str = buf; 1788 break; 1789 case B_AT_TMEMBER: 1790 idx = (unsigned long)ba->ba_key; 1791 bv = ba->ba_value; 1792 /* Uninitialized tuple */ 1793 if (bv->bv_value == NULL) { 1794 str = buf; 1795 break; 1796 } 1797 ba = bv->bv_value; 1798 assert(ba->ba_type == B_AT_TUPLE); 1799 ba = ba->ba_value; 1800 while (ba != NULL && idx-- > 0) { 1801 ba = SLIST_NEXT(ba, ba_next); 1802 } 1803 str = ba2str(ba, dtev); 1804 break; 1805 case B_AT_NIL: 1806 str = ""; 1807 break; 1808 case B_AT_BI_KSTACK: 1809 str = builtin_stack(dtev, 1, 0); 1810 break; 1811 case B_AT_BI_USTACK: 1812 str = builtin_stack(dtev, 0, dt_get_offset(dtev->dtev_pid)); 1813 break; 1814 case B_AT_BI_COMM: 1815 str = dtev->dtev_comm; 1816 break; 1817 case B_AT_BI_CPU: 1818 snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu); 1819 str = buf; 1820 break; 1821 case B_AT_BI_PID: 1822 snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid); 1823 str = buf; 1824 break; 1825 case B_AT_BI_TID: 1826 snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid); 1827 str = buf; 1828 break; 1829 case B_AT_BI_NSECS: 1830 snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev)); 1831 str = buf; 1832 break; 1833 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1834 str = builtin_arg(dtev, ba->ba_type); 1835 break; 1836 case B_AT_BI_RETVAL: 1837 snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_retval[0]); 1838 str = buf; 1839 break; 1840 case B_AT_BI_PROBE: 1841 if (dtev->dtev_pbn == EVENT_BEGIN) { 1842 str = "BEGIN"; 1843 break; 1844 } else if (dtev->dtev_pbn == EVENT_END) { 1845 str = "END"; 1846 break; 1847 } 1848 dtpi = &dt_dtpis[dtev->dtev_pbn - 1]; 1849 if (dtpi != NULL) 1850 snprintf(buf, sizeof(buf), "%s:%s:%s", 1851 dtpi->dtpi_prov, dtpi_func(dtpi), dtpi->dtpi_name); 1852 else 1853 snprintf(buf, sizeof(buf), "%u", dtev->dtev_pbn); 1854 str = buf; 1855 break; 1856 case B_AT_MAP: 1857 bv = ba->ba_value; 1858 /* Uninitialized map */ 1859 if (bv->bv_value == NULL) { 1860 str = buf; 1861 break; 1862 } 1863 str = ba2str(map_get((struct map *)bv->bv_value, 1864 ba2hash(ba->ba_key, dtev)), dtev); 1865 break; 1866 case B_AT_VAR: 1867 str = ba2str(ba_read(ba), dtev); 1868 break; 1869 case B_AT_FN_STR: 1870 str = (const char*)(fn_str(ba, dtev, buf))->ba_value; 1871 break; 1872 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1873 snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev)); 1874 str = buf; 1875 break; 1876 case B_AT_MF_COUNT: 1877 case B_AT_MF_MAX: 1878 case B_AT_MF_MIN: 1879 case B_AT_MF_SUM: 1880 assert(0); 1881 break; 1882 default: 1883 xabort("no string conversion for type %d", ba->ba_type); 1884 } 1885 1886 return str; 1887 } 1888 1889 int 1890 ba2flags(struct bt_arg *ba) 1891 { 1892 int flags = 0; 1893 1894 assert(ba->ba_type != B_AT_MAP); 1895 assert(ba->ba_type != B_AT_TUPLE); 1896 1897 switch (ba->ba_type) { 1898 case B_AT_STR: 1899 case B_AT_LONG: 1900 case B_AT_TMEMBER: 1901 case B_AT_VAR: 1902 case B_AT_HIST: 1903 case B_AT_NIL: 1904 break; 1905 case B_AT_BI_KSTACK: 1906 flags |= DTEVT_KSTACK; 1907 break; 1908 case B_AT_BI_USTACK: 1909 flags |= DTEVT_USTACK; 1910 break; 1911 case B_AT_BI_COMM: 1912 flags |= DTEVT_EXECNAME; 1913 break; 1914 case B_AT_BI_CPU: 1915 case B_AT_BI_PID: 1916 case B_AT_BI_TID: 1917 case B_AT_BI_NSECS: 1918 break; 1919 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1920 flags |= DTEVT_FUNCARGS; 1921 break; 1922 case B_AT_BI_RETVAL: 1923 case B_AT_BI_PROBE: 1924 break; 1925 case B_AT_MF_COUNT: 1926 case B_AT_MF_MAX: 1927 case B_AT_MF_MIN: 1928 case B_AT_MF_SUM: 1929 case B_AT_FN_STR: 1930 break; 1931 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1932 flags |= ba2dtflags(ba->ba_value); 1933 break; 1934 default: 1935 xabort("invalid argument type %d", ba->ba_type); 1936 } 1937 1938 return flags; 1939 } 1940 1941 /* 1942 * Return dt(4) flags indicating which data should be recorded by the 1943 * kernel, if any, for a given `ba'. 1944 */ 1945 int 1946 ba2dtflags(struct bt_arg *ba) 1947 { 1948 static long recursions; 1949 struct bt_arg *bval; 1950 int flags = 0; 1951 1952 if (++recursions >= __MAXOPERANDS) 1953 errx(1, "too many operands (>%d) in expression", __MAXOPERANDS); 1954 1955 do { 1956 if (ba->ba_type == B_AT_MAP) 1957 flags |= ba2flags(ba->ba_key); 1958 else if (ba->ba_type == B_AT_TUPLE) { 1959 bval = ba->ba_value; 1960 do { 1961 flags |= ba2flags(bval); 1962 } while ((bval = SLIST_NEXT(bval, ba_next)) != NULL); 1963 } else 1964 flags |= ba2flags(ba); 1965 1966 } while ((ba = SLIST_NEXT(ba, ba_next)) != NULL); 1967 1968 --recursions; 1969 1970 return flags; 1971 } 1972 1973 long 1974 bacmp(struct bt_arg *a, struct bt_arg *b) 1975 { 1976 char astr[STRLEN]; 1977 long val; 1978 1979 if (a->ba_type != b->ba_type) 1980 return a->ba_type - b->ba_type; 1981 1982 switch (a->ba_type) { 1983 case B_AT_LONG: 1984 return ba2long(a, NULL) - ba2long(b, NULL); 1985 case B_AT_STR: 1986 strlcpy(astr, ba2str(a, NULL), sizeof(astr)); 1987 return strcmp(astr, ba2str(b, NULL)); 1988 case B_AT_TUPLE: 1989 /* Compare two lists of arguments one by one. */ 1990 a = a->ba_value; 1991 b = b->ba_value; 1992 do { 1993 val = bacmp(a, b); 1994 if (val != 0) 1995 break; 1996 1997 a = SLIST_NEXT(a, ba_next); 1998 b = SLIST_NEXT(b, ba_next); 1999 if (a == NULL && b != NULL) 2000 val = -1; 2001 else if (a != NULL && b == NULL) 2002 val = 1; 2003 } while (a != NULL && b != NULL); 2004 2005 return val; 2006 default: 2007 xabort("no compare support for type %d", a->ba_type); 2008 } 2009 } 2010 2011 __dead void 2012 xabort(const char *fmt, ...) 2013 { 2014 va_list ap; 2015 2016 va_start(ap, fmt); 2017 vfprintf(stderr, fmt, ap); 2018 va_end(ap); 2019 2020 fprintf(stderr, "\n"); 2021 abort(); 2022 } 2023 2024 void 2025 debug(const char *fmt, ...) 2026 { 2027 va_list ap; 2028 2029 if (verbose < 2) 2030 return; 2031 2032 fprintf(stderr, "debug: "); 2033 2034 va_start(ap, fmt); 2035 vfprintf(stderr, fmt, ap); 2036 va_end(ap); 2037 } 2038 2039 void 2040 debugx(const char *fmt, ...) 2041 { 2042 va_list ap; 2043 2044 if (verbose < 2) 2045 return; 2046 2047 va_start(ap, fmt); 2048 vfprintf(stderr, fmt, ap); 2049 va_end(ap); 2050 } 2051 2052 void 2053 debug_dump_term(struct bt_arg *ba) 2054 { 2055 switch (ba->ba_type) { 2056 case B_AT_LONG: 2057 debugx("%s", ba2str(ba, NULL)); 2058 break; 2059 case B_AT_OP_PLUS ... B_AT_OP_LOR: 2060 debug_dump_expr(ba); 2061 break; 2062 default: 2063 debugx("%s", ba_name(ba)); 2064 } 2065 } 2066 2067 void 2068 debug_dump_expr(struct bt_arg *ba) 2069 { 2070 struct bt_arg *lhs, *rhs; 2071 2072 lhs = ba->ba_value; 2073 rhs = SLIST_NEXT(lhs, ba_next); 2074 2075 /* Left */ 2076 debug_dump_term(lhs); 2077 2078 /* Right */ 2079 if (rhs != NULL) { 2080 debugx(" %s ", ba_name(ba)); 2081 debug_dump_term(rhs); 2082 } else { 2083 if (ba->ba_type != B_AT_OP_NE) 2084 debugx(" %s NULL", ba_name(ba)); 2085 } 2086 } 2087 2088 void 2089 debug_dump_filter(struct bt_rule *r) 2090 { 2091 struct bt_stmt *bs; 2092 2093 if (verbose < 2) 2094 return; 2095 2096 if (r->br_filter == NULL) { 2097 debugx("\n"); 2098 return; 2099 } 2100 2101 bs = r->br_filter->bf_condition; 2102 2103 debugx(" /"); 2104 debug_dump_expr(SLIST_FIRST(&bs->bs_args)); 2105 debugx("/\n"); 2106 } 2107 2108 unsigned long 2109 dt_get_offset(pid_t pid) 2110 { 2111 static struct dtioc_getaux cache[32]; 2112 static int next; 2113 struct dtioc_getaux *aux = NULL; 2114 int i; 2115 2116 for (i = 0; i < 32; i++) { 2117 if (cache[i].dtga_pid != pid) 2118 continue; 2119 aux = cache + i; 2120 break; 2121 } 2122 2123 if (aux == NULL) { 2124 aux = &cache[next++]; 2125 next %= 32; 2126 2127 aux->dtga_pid = pid; 2128 if (ioctl(dtfd, DTIOCGETAUXBASE, aux)) 2129 aux->dtga_auxbase = 0; 2130 } 2131 2132 return aux->dtga_auxbase; 2133 } 2134