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