1 /* $OpenBSD: btrace.c,v 1.61 2021/12/07 22:17:03 guenther 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 389 rules_setup(fd); 390 391 while (!quit_pending && g_nprobes > 0) { 392 static struct dt_evt devtbuf[64]; 393 ssize_t rlen; 394 size_t i; 395 396 rlen = read(fd, devtbuf, sizeof(devtbuf) - 1); 397 if (rlen == -1) { 398 if (errno == EINTR && quit_pending) { 399 printf("\n"); 400 break; 401 } 402 err(1, "read"); 403 } 404 405 if ((rlen % sizeof(struct dt_evt)) != 0) 406 err(1, "incorrect read"); 407 408 for (i = 0; i < rlen / sizeof(struct dt_evt); i++) 409 rules_apply(&devtbuf[i]); 410 } 411 412 rules_teardown(fd); 413 414 if (verbose && fd != -1) { 415 struct dtioc_stat dtst; 416 417 memset(&dtst, 0, sizeof(dtst)); 418 if (ioctl(fd, DTIOCGSTATS, &dtst)) 419 warn("DTIOCGSTATS"); 420 421 printf("%llu events read\n", dtst.dtst_readevt); 422 printf("%llu events dropped\n", dtst.dtst_dropevt); 423 printf("%llu events filtered\n", bt_filtered); 424 } 425 } 426 427 void 428 rules_setup(int fd) 429 { 430 struct dtioc_probe_info *dtpi; 431 struct dtioc_req *dtrq; 432 struct bt_rule *r, *rbegin = NULL; 433 struct bt_probe *bp; 434 struct bt_stmt *bs; 435 int dokstack = 0, on = 1; 436 uint64_t evtflags; 437 438 TAILQ_FOREACH(r, &g_rules, br_next) { 439 evtflags = 0; 440 SLIST_FOREACH(bs, &r->br_action, bs_next) { 441 struct bt_arg *ba; 442 443 SLIST_FOREACH(ba, &bs->bs_args, ba_next) 444 evtflags |= ba2dtflags(ba); 445 446 /* Also check the value for map/hist insertion */ 447 switch (bs->bs_act) { 448 case B_AC_BUCKETIZE: 449 case B_AC_INSERT: 450 ba = (struct bt_arg *)bs->bs_var; 451 evtflags |= ba2dtflags(ba); 452 break; 453 default: 454 break; 455 } 456 } 457 458 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 459 debug("parsed probe '%s'", debug_probe_name(bp)); 460 debug_dump_filter(r); 461 462 if (bp->bp_type != B_PT_PROBE) { 463 if (bp->bp_type == B_PT_BEGIN) 464 rbegin = r; 465 continue; 466 } 467 468 dtpi_cache(fd); 469 dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func, 470 bp->bp_name); 471 if (dtpi == NULL) { 472 errx(1, "probe '%s:%s:%s' not found", 473 bp->bp_prov, bp->bp_func, bp->bp_name); 474 } 475 476 dtrq = calloc(1, sizeof(*dtrq)); 477 if (dtrq == NULL) 478 err(1, "dtrq: 1alloc"); 479 480 bp->bp_pbn = dtpi->dtpi_pbn; 481 dtrq->dtrq_pbn = dtpi->dtpi_pbn; 482 dtrq->dtrq_rate = bp->bp_rate; 483 dtrq->dtrq_evtflags = evtflags; 484 if (dtrq->dtrq_evtflags & DTEVT_KSTACK) 485 dokstack = 1; 486 bp->bp_cookie = dtrq; 487 } 488 } 489 490 if (dokstack) 491 kelf_open(); 492 493 /* Initialize "fake" event for BEGIN/END */ 494 bt_devt.dtev_pbn = -1; 495 memcpy(&bt_devt.dtev_comm, getprogname(), sizeof(bt_devt.dtev_comm)); 496 bt_devt.dtev_pid = getpid(); 497 bt_devt.dtev_tid = getthrid(); 498 clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp); 499 500 if (rbegin) 501 rule_eval(rbegin, &bt_devt); 502 503 /* Enable all probes */ 504 TAILQ_FOREACH(r, &g_rules, br_next) { 505 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 506 if (bp->bp_type != B_PT_PROBE) 507 continue; 508 509 dtrq = bp->bp_cookie; 510 if (ioctl(fd, DTIOCPRBENABLE, dtrq)) 511 err(1, "DTIOCPRBENABLE"); 512 } 513 } 514 515 if (g_nprobes > 0) { 516 if (ioctl(fd, DTIOCRECORD, &on)) 517 err(1, "DTIOCRECORD"); 518 } 519 } 520 521 void 522 rules_apply(struct dt_evt *dtev) 523 { 524 struct bt_rule *r; 525 struct bt_probe *bp; 526 527 TAILQ_FOREACH(r, &g_rules, br_next) { 528 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 529 if (bp->bp_type != B_PT_PROBE || 530 bp->bp_pbn != dtev->dtev_pbn) 531 continue; 532 533 rule_eval(r, dtev); 534 } 535 } 536 } 537 538 void 539 rules_teardown(int fd) 540 { 541 struct dtioc_req *dtrq; 542 struct bt_probe *bp; 543 struct bt_rule *r, *rend = NULL; 544 int dokstack = 0, off = 0; 545 546 if (g_nprobes > 0) { 547 if (ioctl(fd, DTIOCRECORD, &off)) 548 err(1, "DTIOCRECORD"); 549 } 550 551 TAILQ_FOREACH(r, &g_rules, br_next) { 552 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 553 if (bp->bp_type != B_PT_PROBE) { 554 if (bp->bp_type == B_PT_END) 555 rend = r; 556 continue; 557 } 558 559 dtrq = bp->bp_cookie; 560 if (ioctl(fd, DTIOCPRBDISABLE, dtrq)) 561 err(1, "DTIOCPRBDISABLE"); 562 if (dtrq->dtrq_evtflags & DTEVT_KSTACK) 563 dokstack = 1; 564 } 565 } 566 567 if (dokstack) 568 kelf_close(); 569 570 /* Update "fake" event for BEGIN/END */ 571 clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp); 572 573 if (rend) 574 rule_eval(rend, &bt_devt); 575 576 /* Print non-empty map & hist */ 577 TAILQ_FOREACH(r, &g_rules, br_next) 578 rule_printmaps(r); 579 } 580 581 void 582 rule_eval(struct bt_rule *r, struct dt_evt *dtev) 583 { 584 struct bt_stmt *bs; 585 struct bt_probe *bp; 586 587 SLIST_FOREACH(bp, &r->br_probes, bp_next) { 588 debug("eval rule '%s'", debug_probe_name(bp)); 589 debug_dump_filter(r); 590 } 591 592 if (r->br_filter != NULL && r->br_filter->bf_condition != NULL) { 593 if (stmt_test(r->br_filter->bf_condition, dtev) == false) { 594 bt_filtered++; 595 return; 596 } 597 } 598 599 SLIST_FOREACH(bs, &r->br_action, bs_next) { 600 if ((bs->bs_act == B_AC_TEST) && stmt_test(bs, dtev) == true) 601 stmt_eval((struct bt_stmt *)bs->bs_var, dtev); 602 603 stmt_eval(bs, dtev); 604 } 605 } 606 607 void 608 rule_printmaps(struct bt_rule *r) 609 { 610 struct bt_stmt *bs; 611 612 SLIST_FOREACH(bs, &r->br_action, bs_next) { 613 struct bt_arg *ba; 614 615 SLIST_FOREACH(ba, &bs->bs_args, ba_next) { 616 struct bt_var *bv = ba->ba_value; 617 struct map *map; 618 619 if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST) 620 continue; 621 622 map = (struct map *)bv->bv_value; 623 if (map == NULL) 624 continue; 625 626 if (ba->ba_type == B_AT_MAP) 627 map_print(map, SIZE_T_MAX, bv_name(bv)); 628 else 629 hist_print((struct hist *)map, bv_name(bv)); 630 map_clear(map); 631 bv->bv_value = NULL; 632 } 633 } 634 } 635 636 time_t 637 builtin_gettime(struct dt_evt *dtev) 638 { 639 struct timespec ts; 640 641 if (dtev == NULL) { 642 clock_gettime(CLOCK_REALTIME, &ts); 643 return ts.tv_sec; 644 } 645 646 return dtev->dtev_tsp.tv_sec; 647 } 648 649 static inline uint64_t 650 TIMESPEC_TO_NSEC(struct timespec *ts) 651 { 652 return (ts->tv_sec * 1000000000L + ts->tv_nsec); 653 } 654 655 uint64_t 656 builtin_nsecs(struct dt_evt *dtev) 657 { 658 struct timespec ts; 659 660 if (dtev == NULL) { 661 clock_gettime(CLOCK_REALTIME, &ts); 662 return TIMESPEC_TO_NSEC(&ts); 663 } 664 665 return TIMESPEC_TO_NSEC(&dtev->dtev_tsp); 666 } 667 668 const char * 669 builtin_stack(struct dt_evt *dtev, int kernel) 670 { 671 struct stacktrace *st = &dtev->dtev_kstack; 672 static char buf[4096], *bp; 673 size_t i; 674 int sz; 675 676 if (!kernel) 677 return ""; 678 if (st->st_count == 0) 679 return "\nuserland\n"; 680 681 buf[0] = '\0'; 682 bp = buf; 683 sz = sizeof(buf); 684 for (i = 0; i < st->st_count; i++) { 685 int l; 686 687 l = kelf_snprintsym(bp, sz - 1, st->st_pc[i]); 688 if (l < 0) 689 break; 690 if (l >= sz - 1) { 691 bp += sz - 1; 692 sz = 1; 693 break; 694 } 695 bp += l; 696 sz -= l; 697 } 698 snprintf(bp, sz, "\nkernel\n"); 699 700 return buf; 701 } 702 703 const char * 704 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat) 705 { 706 static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */ 707 708 snprintf(buf, sizeof(buf), "%lu", 709 dtev->dtev_args[dat - B_AT_BI_ARG0]); 710 711 return buf; 712 } 713 714 void 715 stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev) 716 { 717 switch (bs->bs_act) { 718 case B_AC_BUCKETIZE: 719 stmt_bucketize(bs, dtev); 720 break; 721 case B_AC_CLEAR: 722 stmt_clear(bs); 723 break; 724 case B_AC_DELETE: 725 stmt_delete(bs, dtev); 726 break; 727 case B_AC_EXIT: 728 exit(0); 729 break; 730 case B_AC_INSERT: 731 stmt_insert(bs, dtev); 732 break; 733 case B_AC_PRINT: 734 stmt_print(bs, dtev); 735 break; 736 case B_AC_PRINTF: 737 stmt_printf(bs, dtev); 738 break; 739 case B_AC_STORE: 740 stmt_store(bs, dtev); 741 break; 742 case B_AC_TEST: 743 /* done before */ 744 break; 745 case B_AC_TIME: 746 stmt_time(bs, dtev); 747 break; 748 case B_AC_ZERO: 749 stmt_zero(bs); 750 break; 751 default: 752 xabort("no handler for action type %d", bs->bs_act); 753 } 754 } 755 756 /* 757 * Increment a bucket: { @h = hist(v); } or { @h = lhist(v, min, max, step); } 758 * 759 * In this case 'h' is represented by `bv' and '(min, max, step)' by `brange'. 760 */ 761 void 762 stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev) 763 { 764 struct bt_arg *brange, *bhist = SLIST_FIRST(&bs->bs_args); 765 struct bt_arg *bval = (struct bt_arg *)bs->bs_var; 766 struct bt_var *bv = bhist->ba_value; 767 const char *bucket; 768 long step = 0; 769 770 assert(bhist->ba_type == B_AT_HIST); 771 assert(SLIST_NEXT(bval, ba_next) == NULL); 772 773 brange = bhist->ba_key; 774 bucket = ba2bucket(bval, brange, dtev, &step); 775 if (bucket == NULL) { 776 debug("hist=%p '%s' value=%lu out of range\n", bv->bv_value, 777 bv_name(bv), ba2long(bval, dtev)); 778 return; 779 } 780 debug("hist=%p '%s' increment bucket '%s'\n", bv->bv_value, 781 bv_name(bv), bucket); 782 783 bv->bv_value = (struct bt_arg *) 784 hist_increment((struct hist *)bv->bv_value, bucket, step); 785 bv->bv_type = B_VT_HIST; 786 } 787 788 789 /* 790 * Empty a map: { clear(@map); } 791 */ 792 void 793 stmt_clear(struct bt_stmt *bs) 794 { 795 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 796 struct bt_var *bv = ba->ba_value; 797 struct map *map; 798 799 assert(bs->bs_var == NULL); 800 assert(ba->ba_type == B_AT_VAR); 801 802 map = (struct map *)bv->bv_value; 803 if (map == NULL) 804 return; 805 806 if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST) 807 errx(1, "invalid variable type for clear(%s)", ba_name(ba)); 808 809 map_clear(map); 810 bv->bv_value = NULL; 811 812 debug("map=%p '%s' clear\n", map, bv_name(bv)); 813 } 814 815 /* 816 * Map delete: { delete(@map[key]); } 817 * 818 * In this case 'map' is represented by `bv' and 'key' by `bkey'. 819 */ 820 void 821 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev) 822 { 823 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 824 struct bt_var *bv = bmap->ba_value; 825 struct map *map; 826 const char *hash; 827 828 assert(bmap->ba_type == B_AT_MAP); 829 assert(bs->bs_var == NULL); 830 831 map = (struct map *)bv->bv_value; 832 if (map == NULL) 833 return; 834 835 bkey = bmap->ba_key; 836 hash = ba2hash(bkey, dtev); 837 debug("map=%p '%s' delete key=%p '%s'\n", map, bv_name(bv), bkey, hash); 838 839 map_delete(map, hash); 840 } 841 842 /* 843 * Map insert: { @map[key] = 42; } 844 * 845 * In this case 'map' is represented by `bv', 'key' by `bkey' and 846 * '42' by `bval'. 847 */ 848 void 849 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev) 850 { 851 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 852 struct bt_arg *bval = (struct bt_arg *)bs->bs_var; 853 struct bt_var *bv = bmap->ba_value; 854 struct map *map; 855 const char *hash; 856 857 assert(bmap->ba_type == B_AT_MAP); 858 assert(SLIST_NEXT(bval, ba_next) == NULL); 859 860 bkey = bmap->ba_key; 861 hash = ba2hash(bkey, dtev); 862 863 /* map is NULL before first insert or after clear() */ 864 map = (struct map *)bv->bv_value; 865 map = map_insert(map, hash, bval, dtev); 866 867 debug("map=%p '%s' insert key=%p '%s' bval=%p\n", map, 868 bv_name(bv), bkey, hash, bval); 869 870 bv->bv_value = (struct bt_arg *)map; 871 bv->bv_type = B_VT_MAP; 872 } 873 874 /* 875 * Print variables: { print(890); print(@map[, 8]); print(comm); } 876 * 877 * In this case the global variable 'map' is pointed at by `ba' 878 * and '8' is represented by `btop'. 879 */ 880 void 881 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev) 882 { 883 struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args); 884 struct bt_var *bv = ba->ba_value; 885 struct map *map; 886 size_t top = SIZE_T_MAX; 887 888 assert(bs->bs_var == NULL); 889 890 /* Parse optional `top' argument. */ 891 btop = SLIST_NEXT(ba, ba_next); 892 if (btop != NULL) { 893 assert(SLIST_NEXT(btop, ba_next) == NULL); 894 top = ba2long(btop, dtev); 895 } 896 897 /* Static argument. */ 898 if (ba->ba_type != B_AT_VAR) { 899 assert(btop == NULL); 900 printf("%s\n", ba2str(ba, dtev)); 901 return; 902 } 903 904 map = (struct map *)bv->bv_value; 905 if (map == NULL) 906 return; 907 908 debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top); 909 910 if (bv->bv_type == B_VT_MAP) 911 map_print(map, top, bv_name(bv)); 912 else if (bv->bv_type == B_VT_HIST) 913 hist_print((struct hist *)map, bv_name(bv)); 914 else 915 printf("%s\n", ba2str(ba, dtev)); 916 } 917 918 /* 919 * Variable store: { @var = 3; } 920 * 921 * In this case '3' is represented by `ba', the argument of a STORE 922 * action. 923 * 924 * If the argument depends of the value of an event (builtin) or is 925 * the result of an operation, its evaluation is stored in a new `ba'. 926 */ 927 void 928 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev) 929 { 930 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 931 struct bt_var *bv = bs->bs_var; 932 933 assert(SLIST_NEXT(ba, ba_next) == NULL); 934 935 switch (ba->ba_type) { 936 case B_AT_STR: 937 bv->bv_value = ba; 938 bv->bv_type = B_VT_STR; 939 break; 940 case B_AT_LONG: 941 bv->bv_value = ba; 942 bv->bv_type = B_VT_LONG; 943 break; 944 case B_AT_BI_NSECS: 945 bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG); 946 bv->bv_type = B_VT_LONG; 947 break; 948 case B_AT_OP_PLUS ... B_AT_OP_LOR: 949 bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG); 950 bv->bv_type = B_VT_LONG; 951 break; 952 case B_AT_FN_STR: 953 bv->bv_value = ba_new(ba2str(ba, dtev), B_AT_STR); 954 bv->bv_type = B_VT_STR; 955 break; 956 default: 957 xabort("store not implemented for type %d", ba->ba_type); 958 } 959 960 debug("bv=%p var '%s' store (%p)\n", bv, bv_name(bv), bv->bv_value); 961 } 962 963 /* 964 * String conversion { str($1); string($1, 3); } 965 * 966 * Since fn_str is currently only called in ba2str, *buf should be a pointer 967 * to the static buffer provided by ba2str. 968 */ 969 struct bt_arg * 970 fn_str(struct bt_arg *ba, struct dt_evt *dtev, char *buf) 971 { 972 struct bt_arg *arg, *index; 973 ssize_t len = STRLEN; 974 975 assert(ba->ba_type == B_AT_FN_STR); 976 977 arg = (struct bt_arg*)ba->ba_value; 978 assert(arg != NULL); 979 980 index = SLIST_NEXT(arg, ba_next); 981 if (index != NULL) { 982 /* Should have only 1 optional argument. */ 983 assert(SLIST_NEXT(index, ba_next) == NULL); 984 len = MINIMUM(ba2long(index, dtev) + 1, STRLEN); 985 } 986 987 /* All negative lengths behave the same as a zero length. */ 988 if (len < 1) 989 return ba_new("", B_AT_STR); 990 991 strlcpy(buf, ba2str(arg, dtev), len); 992 return ba_new(buf, B_AT_STR); 993 } 994 995 /* 996 * Expression test: { if (expr) stmt; } 997 */ 998 bool 999 stmt_test(struct bt_stmt *bs, struct dt_evt *dtev) 1000 { 1001 struct bt_arg *ba; 1002 1003 if (bs == NULL) 1004 return true; 1005 1006 ba = SLIST_FIRST(&bs->bs_args); 1007 1008 return baexpr2long(ba, dtev) != 0; 1009 } 1010 1011 /* 1012 * Print time: { time("%H:%M:%S"); } 1013 */ 1014 void 1015 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev) 1016 { 1017 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 1018 time_t time; 1019 struct tm *tm; 1020 char buf[64]; 1021 1022 assert(bs->bs_var == NULL); 1023 assert(ba->ba_type == B_AT_STR); 1024 assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1)); 1025 1026 time = builtin_gettime(dtev); 1027 tm = localtime(&time); 1028 strftime(buf, sizeof(buf), ba2str(ba, dtev), tm); 1029 printf("%s", buf); 1030 } 1031 1032 /* 1033 * Set entries to 0: { zero(@map); } 1034 */ 1035 void 1036 stmt_zero(struct bt_stmt *bs) 1037 { 1038 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 1039 struct bt_var *bv = ba->ba_value; 1040 struct map *map; 1041 1042 assert(bs->bs_var == NULL); 1043 assert(ba->ba_type == B_AT_VAR); 1044 1045 map = (struct map *)bv->bv_value; 1046 if (map == NULL) 1047 return; 1048 1049 if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST) 1050 errx(1, "invalid variable type for zero(%s)", ba_name(ba)); 1051 1052 map_zero(map); 1053 1054 debug("map=%p '%s' zero\n", map, bv_name(bv)); 1055 } 1056 1057 struct bt_arg * 1058 ba_read(struct bt_arg *ba) 1059 { 1060 struct bt_var *bv = ba->ba_value; 1061 1062 assert(ba->ba_type == B_AT_VAR); 1063 1064 debug("bv=%p read '%s' (%p)\n", bv, bv_name(bv), bv->bv_value); 1065 1066 /* Handle map/hist access after clear(). */ 1067 if (bv->bv_value == NULL) 1068 return &g_nullba; 1069 1070 return bv->bv_value; 1071 } 1072 1073 const char * 1074 ba2hash(struct bt_arg *ba, struct dt_evt *dtev) 1075 { 1076 static char buf[KLEN]; 1077 char *hash; 1078 int l, len; 1079 1080 buf[0] = '\0'; 1081 l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev)); 1082 if (l < 0 || (size_t)l > sizeof(buf)) { 1083 warn("string too long %d > %lu", l, sizeof(buf)); 1084 return buf; 1085 } 1086 1087 len = 0; 1088 while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) { 1089 len += l; 1090 hash = buf + len; 1091 1092 l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev)); 1093 if (l < 0 || (size_t)l > (sizeof(buf) - len)) { 1094 warn("hash too long %d > %lu", l + len, sizeof(buf)); 1095 break; 1096 } 1097 } 1098 1099 return buf; 1100 } 1101 1102 static unsigned long 1103 next_pow2(unsigned long x) 1104 { 1105 size_t i; 1106 1107 x--; 1108 for (i = 0; i < (sizeof(x) * 8) - 1; i++) 1109 x |= (x >> 1); 1110 1111 return x + 1; 1112 } 1113 1114 /* 1115 * Return the ceiling value the interval holding `ba' or NULL if it is 1116 * out of the (min, max) values. 1117 */ 1118 const char * 1119 ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev, 1120 long *pstep) 1121 { 1122 static char buf[KLEN]; 1123 long val, bucket; 1124 int l; 1125 1126 val = ba2long(ba, dtev); 1127 if (brange == NULL) 1128 bucket = next_pow2(val); 1129 else { 1130 long min, max, step; 1131 1132 assert(brange->ba_type == B_AT_LONG); 1133 min = ba2long(brange, NULL); 1134 1135 brange = SLIST_NEXT(brange, ba_next); 1136 assert(brange->ba_type == B_AT_LONG); 1137 max = ba2long(brange, NULL); 1138 1139 if ((val < min) || (val > max)) 1140 return NULL; 1141 1142 brange = SLIST_NEXT(brange, ba_next); 1143 assert(brange->ba_type == B_AT_LONG); 1144 step = ba2long(brange, NULL); 1145 1146 bucket = ((val / step) + 1) * step; 1147 *pstep = step; 1148 } 1149 1150 buf[0] = '\0'; 1151 l = snprintf(buf, sizeof(buf), "%lu", bucket); 1152 if (l < 0 || (size_t)l > sizeof(buf)) { 1153 warn("string too long %d > %lu", l, sizeof(buf)); 1154 return buf; 1155 } 1156 1157 return buf; 1158 } 1159 1160 /* 1161 * Evaluate the operation encoded in `ba' and return its result. 1162 */ 1163 long 1164 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev) 1165 { 1166 static long recursions; 1167 struct bt_arg *lhs, *rhs; 1168 long lval, rval, result; 1169 1170 if (++recursions >= __MAXOPERANDS) 1171 errx(1, "too many operands (>%d) in expression", __MAXOPERANDS); 1172 1173 lhs = ba->ba_value; 1174 rhs = SLIST_NEXT(lhs, ba_next); 1175 1176 lval = ba2long(lhs, dtev); 1177 if (rhs == NULL) { 1178 rval = 0; 1179 } else { 1180 assert(SLIST_NEXT(rhs, ba_next) == NULL); 1181 rval = ba2long(rhs, dtev); 1182 } 1183 1184 switch (ba->ba_type) { 1185 case B_AT_OP_PLUS: 1186 result = lval + rval; 1187 break; 1188 case B_AT_OP_MINUS: 1189 result = lval - rval; 1190 break; 1191 case B_AT_OP_MULT: 1192 result = lval * rval; 1193 break; 1194 case B_AT_OP_DIVIDE: 1195 result = lval / rval; 1196 break; 1197 case B_AT_OP_BAND: 1198 result = lval & rval; 1199 break; 1200 case B_AT_OP_XOR: 1201 result = lval ^ rval; 1202 break; 1203 case B_AT_OP_BOR: 1204 result = lval | rval; 1205 break; 1206 case B_AT_OP_EQ: 1207 result = (lval == rval); 1208 break; 1209 case B_AT_OP_NE: 1210 result = (lval != rval); 1211 break; 1212 case B_AT_OP_LE: 1213 result = (lval <= rval); 1214 break; 1215 case B_AT_OP_LT: 1216 result = (lval < rval); 1217 break; 1218 case B_AT_OP_GE: 1219 result = (lval >= rval); 1220 break; 1221 case B_AT_OP_GT: 1222 result = (lval > rval); 1223 break; 1224 case B_AT_OP_LAND: 1225 result = (lval && rval); 1226 break; 1227 case B_AT_OP_LOR: 1228 result = (lval || rval); 1229 break; 1230 default: 1231 xabort("unsuported operation %d", ba->ba_type); 1232 } 1233 1234 debug("ba=%p eval '%ld %s %ld = %d'\n", ba, lval, ba_name(ba), 1235 rval, result); 1236 1237 --recursions; 1238 1239 return result; 1240 } 1241 1242 const char * 1243 ba_name(struct bt_arg *ba) 1244 { 1245 switch (ba->ba_type) { 1246 case B_AT_NIL: 1247 return "0"; 1248 case B_AT_VAR: 1249 case B_AT_MAP: 1250 break; 1251 case B_AT_BI_PID: 1252 return "pid"; 1253 case B_AT_BI_TID: 1254 return "tid"; 1255 case B_AT_BI_COMM: 1256 return "comm"; 1257 case B_AT_BI_CPU: 1258 return "cpu"; 1259 case B_AT_BI_NSECS: 1260 return "nsecs"; 1261 case B_AT_BI_KSTACK: 1262 return "kstack"; 1263 case B_AT_BI_USTACK: 1264 return "ustack"; 1265 case B_AT_BI_ARG0: 1266 return "arg0"; 1267 case B_AT_BI_ARG1: 1268 return "arg1"; 1269 case B_AT_BI_ARG2: 1270 return "arg2"; 1271 case B_AT_BI_ARG3: 1272 return "arg3"; 1273 case B_AT_BI_ARG4: 1274 return "arg4"; 1275 case B_AT_BI_ARG5: 1276 return "arg5"; 1277 case B_AT_BI_ARG6: 1278 return "arg6"; 1279 case B_AT_BI_ARG7: 1280 return "arg7"; 1281 case B_AT_BI_ARG8: 1282 return "arg8"; 1283 case B_AT_BI_ARG9: 1284 return "arg9"; 1285 case B_AT_BI_ARGS: 1286 return "args"; 1287 case B_AT_BI_RETVAL: 1288 return "retval"; 1289 case B_AT_BI_PROBE: 1290 return "probe"; 1291 case B_AT_FN_STR: 1292 return "str"; 1293 case B_AT_OP_PLUS: 1294 return "+"; 1295 case B_AT_OP_MINUS: 1296 return "-"; 1297 case B_AT_OP_MULT: 1298 return "*"; 1299 case B_AT_OP_DIVIDE: 1300 return "/"; 1301 case B_AT_OP_BAND: 1302 return "&"; 1303 case B_AT_OP_XOR: 1304 return "^"; 1305 case B_AT_OP_BOR: 1306 return "|"; 1307 case B_AT_OP_EQ: 1308 return "=="; 1309 case B_AT_OP_NE: 1310 return "!="; 1311 case B_AT_OP_LE: 1312 return "<="; 1313 case B_AT_OP_LT: 1314 return "<"; 1315 case B_AT_OP_GE: 1316 return ">="; 1317 case B_AT_OP_GT: 1318 return ">"; 1319 case B_AT_OP_LAND: 1320 return "&&"; 1321 case B_AT_OP_LOR: 1322 return "||"; 1323 default: 1324 xabort("unsuported type %d", ba->ba_type); 1325 } 1326 1327 assert(ba->ba_type == B_AT_VAR || ba->ba_type == B_AT_MAP); 1328 1329 static char buf[64]; 1330 size_t sz; 1331 int l; 1332 1333 buf[0] = '@'; 1334 buf[1] = '\0'; 1335 sz = sizeof(buf) - 1; 1336 l = snprintf(buf+1, sz, "%s", bv_name(ba->ba_value)); 1337 if (l < 0 || (size_t)l > sz) { 1338 warn("string too long %d > %zu", l, sz); 1339 return buf; 1340 } 1341 1342 if (ba->ba_type == B_AT_MAP) { 1343 sz -= l; 1344 l = snprintf(buf+1+l, sz, "[%s]", ba_name(ba->ba_key)); 1345 if (l < 0 || (size_t)l > sz) { 1346 warn("string too long %d > %zu", l, sz); 1347 return buf; 1348 } 1349 } 1350 1351 return buf; 1352 } 1353 1354 /* 1355 * Return the representation of `ba' as long. 1356 */ 1357 long 1358 ba2long(struct bt_arg *ba, struct dt_evt *dtev) 1359 { 1360 struct bt_var *bv; 1361 long val; 1362 1363 switch (ba->ba_type) { 1364 case B_AT_LONG: 1365 val = (long)ba->ba_value; 1366 break; 1367 case B_AT_VAR: 1368 ba = ba_read(ba); 1369 val = (long)ba->ba_value; 1370 break; 1371 case B_AT_MAP: 1372 bv = ba->ba_value; 1373 /* Unitialized map */ 1374 if (bv->bv_value == NULL) 1375 return 0; 1376 val = ba2long(map_get((struct map *)bv->bv_value, 1377 ba2str(ba->ba_key, dtev)), dtev); 1378 break; 1379 case B_AT_NIL: 1380 val = 0L; 1381 break; 1382 case B_AT_BI_PID: 1383 val = dtev->dtev_pid; 1384 break; 1385 case B_AT_BI_TID: 1386 val = dtev->dtev_tid; 1387 break; 1388 case B_AT_BI_CPU: 1389 val = dtev->dtev_cpu; 1390 break; 1391 case B_AT_BI_NSECS: 1392 val = builtin_nsecs(dtev); 1393 break; 1394 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1395 val = dtev->dtev_args[ba->ba_type - B_AT_BI_ARG0]; 1396 break; 1397 case B_AT_BI_RETVAL: 1398 val = dtev->dtev_retval[0]; 1399 break; 1400 case B_AT_BI_PROBE: 1401 val = dtev->dtev_pbn; 1402 break; 1403 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1404 val = baexpr2long(ba, dtev); 1405 break; 1406 default: 1407 xabort("no long conversion for type %d", ba->ba_type); 1408 } 1409 1410 return val; 1411 } 1412 1413 /* 1414 * Return the representation of `ba' as string. 1415 */ 1416 const char * 1417 ba2str(struct bt_arg *ba, struct dt_evt *dtev) 1418 { 1419 static char buf[STRLEN]; 1420 struct bt_var *bv; 1421 struct dtioc_probe_info *dtpi; 1422 const char *str; 1423 1424 buf[0] = '\0'; 1425 switch (ba->ba_type) { 1426 case B_AT_STR: 1427 str = (const char *)ba->ba_value; 1428 break; 1429 case B_AT_LONG: 1430 snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value); 1431 str = buf; 1432 break; 1433 case B_AT_NIL: 1434 str = ""; 1435 break; 1436 case B_AT_BI_KSTACK: 1437 str = builtin_stack(dtev, 1); 1438 break; 1439 case B_AT_BI_USTACK: 1440 str = builtin_stack(dtev, 0); 1441 break; 1442 case B_AT_BI_COMM: 1443 str = dtev->dtev_comm; 1444 break; 1445 case B_AT_BI_CPU: 1446 snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu); 1447 str = buf; 1448 break; 1449 case B_AT_BI_PID: 1450 snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid); 1451 str = buf; 1452 break; 1453 case B_AT_BI_TID: 1454 snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid); 1455 str = buf; 1456 break; 1457 case B_AT_BI_NSECS: 1458 snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev)); 1459 str = buf; 1460 break; 1461 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1462 str = builtin_arg(dtev, ba->ba_type); 1463 break; 1464 case B_AT_BI_RETVAL: 1465 snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_retval[0]); 1466 str = buf; 1467 break; 1468 case B_AT_BI_PROBE: 1469 dtpi = dtpi_get_by_id(dtev->dtev_pbn); 1470 if (dtpi != NULL) 1471 snprintf(buf, sizeof(buf), "%s:%s:%s", 1472 dtpi->dtpi_prov, dtpi_func(dtpi), dtpi->dtpi_name); 1473 else 1474 snprintf(buf, sizeof(buf), "%u", dtev->dtev_pbn); 1475 str = buf; 1476 break; 1477 case B_AT_MAP: 1478 bv = ba->ba_value; 1479 /* Unitialized map */ 1480 if (bv->bv_value == NULL) { 1481 str = buf; 1482 break; 1483 } 1484 str = ba2str(map_get((struct map *)bv->bv_value, 1485 ba2str(ba->ba_key, dtev)), dtev); 1486 break; 1487 case B_AT_VAR: 1488 str = ba2str(ba_read(ba), dtev); 1489 break; 1490 case B_AT_FN_STR: 1491 str = (const char*)(fn_str(ba, dtev, buf))->ba_value; 1492 break; 1493 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1494 snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev)); 1495 str = buf; 1496 break; 1497 case B_AT_MF_COUNT: 1498 case B_AT_MF_MAX: 1499 case B_AT_MF_MIN: 1500 case B_AT_MF_SUM: 1501 assert(0); 1502 break; 1503 default: 1504 xabort("no string conversion for type %d", ba->ba_type); 1505 } 1506 1507 return str; 1508 } 1509 1510 /* 1511 * Return dt(4) flags indicating which data should be recorded by the 1512 * kernel, if any, for a given `ba'. 1513 */ 1514 int 1515 ba2dtflags(struct bt_arg *ba) 1516 { 1517 struct bt_arg *bval; 1518 int flags = 0; 1519 1520 do { 1521 if (ba->ba_type == B_AT_MAP) 1522 bval = ba->ba_key; 1523 else 1524 bval = ba; 1525 1526 switch (bval->ba_type) { 1527 case B_AT_STR: 1528 case B_AT_LONG: 1529 case B_AT_VAR: 1530 case B_AT_HIST: 1531 case B_AT_NIL: 1532 break; 1533 case B_AT_BI_KSTACK: 1534 flags |= DTEVT_KSTACK; 1535 break; 1536 case B_AT_BI_USTACK: 1537 flags |= DTEVT_USTACK; 1538 break; 1539 case B_AT_BI_COMM: 1540 flags |= DTEVT_EXECNAME; 1541 break; 1542 case B_AT_BI_CPU: 1543 case B_AT_BI_PID: 1544 case B_AT_BI_TID: 1545 case B_AT_BI_NSECS: 1546 break; 1547 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 1548 flags |= DTEVT_FUNCARGS; 1549 break; 1550 case B_AT_BI_RETVAL: 1551 case B_AT_BI_PROBE: 1552 break; 1553 case B_AT_MF_COUNT: 1554 case B_AT_MF_MAX: 1555 case B_AT_MF_MIN: 1556 case B_AT_MF_SUM: 1557 case B_AT_FN_STR: 1558 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1559 break; 1560 default: 1561 xabort("invalid argument type %d", bval->ba_type); 1562 } 1563 } while ((ba = SLIST_NEXT(ba, ba_next)) != NULL); 1564 1565 return flags; 1566 } 1567 1568 long 1569 bacmp(struct bt_arg *a, struct bt_arg *b) 1570 { 1571 assert(a->ba_type == b->ba_type); 1572 assert(a->ba_type == B_AT_LONG); 1573 1574 return ba2long(a, NULL) - ba2long(b, NULL); 1575 } 1576 1577 __dead void 1578 xabort(const char *fmt, ...) 1579 { 1580 va_list ap; 1581 1582 va_start(ap, fmt); 1583 vfprintf(stderr, fmt, ap); 1584 va_end(ap); 1585 1586 fprintf(stderr, "\n"); 1587 abort(); 1588 } 1589 1590 void 1591 debug(const char *fmt, ...) 1592 { 1593 va_list ap; 1594 1595 if (verbose < 2) 1596 return; 1597 1598 fprintf(stderr, "debug: "); 1599 1600 va_start(ap, fmt); 1601 vfprintf(stderr, fmt, ap); 1602 va_end(ap); 1603 } 1604 1605 void 1606 debugx(const char *fmt, ...) 1607 { 1608 va_list ap; 1609 1610 if (verbose < 2) 1611 return; 1612 1613 va_start(ap, fmt); 1614 vfprintf(stderr, fmt, ap); 1615 va_end(ap); 1616 } 1617 1618 void 1619 debug_dump_term(struct bt_arg *ba) 1620 { 1621 switch (ba->ba_type) { 1622 case B_AT_LONG: 1623 debugx("%s", ba2str(ba, NULL)); 1624 break; 1625 case B_AT_OP_PLUS ... B_AT_OP_LOR: 1626 debug_dump_expr(ba); 1627 break; 1628 default: 1629 debugx("%s", ba_name(ba)); 1630 } 1631 } 1632 1633 void 1634 debug_dump_expr(struct bt_arg *ba) 1635 { 1636 struct bt_arg *lhs, *rhs; 1637 1638 lhs = ba->ba_value; 1639 rhs = SLIST_NEXT(lhs, ba_next); 1640 1641 /* Left */ 1642 debug_dump_term(lhs); 1643 1644 /* Right */ 1645 if (rhs != NULL) { 1646 debugx(" %s ", ba_name(ba)); 1647 debug_dump_term(rhs); 1648 } else { 1649 if (ba->ba_type != B_AT_OP_NE) 1650 debugx(" %s NULL", ba_name(ba)); 1651 } 1652 } 1653 1654 void 1655 debug_dump_filter(struct bt_rule *r) 1656 { 1657 struct bt_stmt *bs; 1658 1659 if (verbose < 2) 1660 return; 1661 1662 if (r->br_filter == NULL) { 1663 debugx("\n"); 1664 return; 1665 } 1666 1667 bs = r->br_filter->bf_condition; 1668 1669 debugx(" /"); 1670 debug_dump_expr(SLIST_FIRST(&bs->bs_args)); 1671 debugx("/\n"); 1672 } 1673 1674 const char * 1675 debug_probe_name(struct bt_probe *bp) 1676 { 1677 static char buf[64]; 1678 1679 if (verbose < 2) 1680 return ""; 1681 1682 if (bp->bp_type == B_PT_BEGIN) 1683 return "BEGIN"; 1684 1685 if (bp->bp_type == B_PT_END) 1686 return "END"; 1687 1688 assert(bp->bp_type == B_PT_PROBE); 1689 1690 if (bp->bp_rate) { 1691 snprintf(buf, sizeof(buf), "%s:%s:%u", bp->bp_prov, 1692 bp->bp_unit, bp->bp_rate); 1693 } else { 1694 snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov, 1695 bp->bp_unit, bp->bp_name); 1696 } 1697 1698 return buf; 1699 } 1700