1 /* $OpenBSD: btrace.c,v 1.4 2020/01/28 16:39:51 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 2019 - 2020 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/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 <signal.h> 31 #include <stdarg.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <time.h> 36 #include <unistd.h> 37 38 #include <dev/dt/dtvar.h> 39 40 #include "btrace.h" 41 #include "bt_parser.h" 42 43 /* 44 * Maximum number of operands an arithmetic operation can have. This 45 * is necessary to stop infinite recursion when evaluating expressions. 46 */ 47 #define __MAXOPERANDS 5 48 49 #define __PATH_DEVDT "/dev/dt" 50 51 __dead void usage(void); 52 char *read_btfile(const char *); 53 54 /* 55 * Retrieve & parse probe information. 56 */ 57 void dtpi_cache(int); 58 void dtpi_print_list(void); 59 char *dtpi_func(struct dtioc_probe_info *); 60 int dtpi_is_unit(const char *); 61 struct dtioc_probe_info *dtpi_get_by_value(const char *, const char *, 62 const char *); 63 64 /* 65 * Main loop and rule evaluation. 66 */ 67 void rules_do(int); 68 void rules_setup(int); 69 void rules_apply(struct dt_evt *); 70 void rules_teardown(int); 71 void rule_eval(struct bt_rule *, struct dt_evt *); 72 73 /* 74 * Language builtins & functions. 75 */ 76 uint64_t builtin_nsecs(struct dt_evt *); 77 const char *builtin_kstack(struct dt_evt *); 78 const char *builtin_arg(struct dt_evt *, enum bt_argtype); 79 void stmt_clear(struct bt_stmt *); 80 void stmt_delete(struct bt_stmt *, struct dt_evt *); 81 void stmt_insert(struct bt_stmt *, struct dt_evt *); 82 void stmt_print(struct bt_stmt *, struct dt_evt *); 83 void stmt_store(struct bt_stmt *, struct dt_evt *); 84 void stmt_time(struct bt_stmt *, struct dt_evt *); 85 void stmt_zero(struct bt_stmt *); 86 struct bt_arg *ba_read(struct bt_arg *); 87 88 /* FIXME: use a real hash. */ 89 #define ba2hash(_b, _e) ba2str((_b), (_e)) 90 91 /* 92 * Debug routines. 93 */ 94 __dead void xabort(const char *, ...); 95 void debug(const char *, ...); 96 void debugx(const char *, ...); 97 const char *debug_rule_name(struct bt_rule *); 98 void debug_dump_filter(struct bt_rule *); 99 void debug_dump_rule(struct bt_rule *); 100 101 struct dtioc_probe_info *dt_dtpis; /* array of available probes */ 102 size_t dt_ndtpi; /* # of elements in the array */ 103 104 int verbose = 0; 105 volatile sig_atomic_t quit_pending; 106 107 static void 108 signal_handler(int sig) 109 { 110 quit_pending = sig; 111 } 112 113 114 int 115 main(int argc, char *argv[]) 116 { 117 int fd = -1, ch, error = 0; 118 const char *filename = NULL, *btscript = NULL; 119 int showprobes = 0; 120 121 setlocale(LC_ALL, ""); 122 123 #if notyet 124 if (pledge("stdio rpath", NULL) == -1) 125 err(1, "pledge"); 126 #endif 127 128 while ((ch = getopt(argc, argv, "e:lv")) != -1) { 129 switch (ch) { 130 case 'e': 131 btscript = optarg; 132 break; 133 case 'l': 134 showprobes = 1; 135 break; 136 case 'v': 137 verbose++; 138 break; 139 default: 140 usage(); 141 } 142 } 143 144 argc -= optind; 145 argv += optind; 146 147 if (argc > 0) { 148 if (btscript != NULL) 149 usage(); 150 151 filename = argv[0]; 152 btscript = read_btfile(filename); 153 argc--; 154 argv++; 155 } 156 157 if (argc != 0 || (btscript == NULL && !showprobes)) 158 usage(); 159 160 if (btscript != NULL) { 161 error = btparse(btscript, strlen(btscript), filename, 1); 162 if (error) 163 return error; 164 } 165 166 if (showprobes || g_nprobes > 0) { 167 fd = open(__PATH_DEVDT, O_RDONLY); 168 if (fd == -1) 169 err(1, "could not open %s", __PATH_DEVDT); 170 } 171 172 if (showprobes) { 173 dtpi_cache(fd); 174 dtpi_print_list(); 175 } 176 177 if (!TAILQ_EMPTY(&g_rules)) 178 rules_do(fd); 179 180 if (fd != -1) 181 close(fd); 182 183 return error; 184 } 185 186 __dead void 187 usage(void) 188 { 189 fprintf(stderr, "usage: %s [-lv] [-e program|file]\n", 190 getprogname()); 191 exit(1); 192 } 193 194 char * 195 read_btfile(const char *filename) 196 { 197 static char fcontent[BUFSIZ]; 198 long offset; 199 FILE *fp; 200 201 fp = fopen(filename, "r"); 202 if (fp == NULL) 203 err(1, "can't open '%s'", filename); 204 205 if (fread(fcontent, sizeof(fcontent) - 1, 1, fp) == 0 && errno != 0) 206 err(1, "can't read '%s'", filename); 207 208 fseek(fp, 0, SEEK_END); 209 offset = ftell(fp); 210 if ((size_t)offset >= sizeof(fcontent)) 211 errx(1, "couldn't read all of '%s'", filename); 212 213 fclose(fp); 214 return fcontent; 215 } 216 217 void 218 dtpi_cache(int fd) 219 { 220 struct dtioc_probe dtpr; 221 222 if (dt_dtpis != NULL) 223 return; 224 225 memset(&dtpr, 0, sizeof(dtpr)); 226 if (ioctl(fd, DTIOCGPLIST, &dtpr)) 227 err(1, "DTIOCGPLIST"); 228 229 dt_ndtpi = (dtpr.dtpr_size / sizeof(*dt_dtpis)); 230 dt_dtpis = reallocarray(NULL, dt_ndtpi, sizeof(*dt_dtpis)); 231 if (dt_dtpis == NULL) 232 err(1, "malloc"); 233 234 dtpr.dtpr_probes = dt_dtpis; 235 if (ioctl(fd, DTIOCGPLIST, &dtpr)) 236 err(1, "DTIOCGPLIST"); 237 } 238 239 void 240 dtpi_print_list(void) 241 { 242 struct dtioc_probe_info *dtpi; 243 size_t i; 244 245 dtpi = dt_dtpis; 246 for (i = 0; i < dt_ndtpi; i++, dtpi++) { 247 printf("%s:%s:%s\n", dtpi->dtpi_prov, dtpi_func(dtpi), 248 dtpi->dtpi_name); 249 } 250 } 251 252 char * 253 dtpi_func(struct dtioc_probe_info *dtpi) 254 { 255 char *sysnb, func[DTNAMESIZE]; 256 const char *errstr; 257 int idx; 258 259 if (strncmp(dtpi->dtpi_prov, "syscall", DTNAMESIZE)) 260 return dtpi->dtpi_func; 261 262 /* Translate syscall names */ 263 strlcpy(func, dtpi->dtpi_func, sizeof(func)); 264 sysnb = func; 265 if (strsep(&sysnb, "%") == NULL) 266 return dtpi->dtpi_func; 267 268 idx = strtonum(sysnb, 1, SYS_MAXSYSCALL, &errstr); 269 if (errstr != NULL) 270 return dtpi->dtpi_func; 271 272 return syscallnames[idx]; 273 } 274 275 int 276 dtpi_is_unit(const char *unit) 277 { 278 return !strncmp("hz", unit, sizeof("hz")); 279 } 280 281 struct dtioc_probe_info * 282 dtpi_get_by_value(const char *prov, const char *func, const char *name) 283 { 284 struct dtioc_probe_info *dtpi; 285 size_t i; 286 287 dtpi = dt_dtpis; 288 for (i = 0; i < dt_ndtpi; i++, dtpi++) { 289 if (prov != NULL && 290 strncmp(prov, dtpi->dtpi_prov, DTNAMESIZE)) 291 continue; 292 293 if (func != NULL) { 294 if (dtpi_is_unit(func)) 295 return dtpi; 296 297 if (strncmp(func, dtpi_func(dtpi), DTNAMESIZE)) 298 continue; 299 } 300 301 if (strncmp(name, dtpi->dtpi_name, DTNAMESIZE)) 302 continue; 303 304 debug("matched probe %s:%s:%s\n", dtpi->dtpi_prov, 305 dtpi_func(dtpi), dtpi->dtpi_name); 306 return dtpi; 307 } 308 309 return NULL; 310 } 311 312 void 313 rules_do(int fd) 314 { 315 struct sigaction sa; 316 317 memset(&sa, 0, sizeof(sa)); 318 sigemptyset(&sa.sa_mask); 319 sa.sa_flags = 0; 320 sa.sa_handler = signal_handler; 321 if (sigaction(SIGINT, &sa, NULL)) 322 err(1, "sigaction"); 323 324 rules_setup(fd); 325 326 while (!quit_pending && g_nprobes > 0) { 327 static struct dt_evt devtbuf[64]; 328 ssize_t rlen; 329 size_t i; 330 331 rlen = read(fd, devtbuf, sizeof(devtbuf) - 1); 332 if (rlen == -1) { 333 if (errno == EINTR && quit_pending) 334 break; 335 err(1, "read"); 336 } 337 338 if ((rlen % sizeof(struct dt_evt)) != 0) 339 err(1, "incorrect read"); 340 341 342 for (i = 0; i < nitems(devtbuf); i++) { 343 struct dt_evt *dtev = &devtbuf[i]; 344 345 if (dtev->dtev_tid == 0) 346 break; 347 348 rules_apply(dtev); 349 } 350 } 351 352 rules_teardown(fd); 353 354 if (verbose && fd != -1) { 355 struct dtioc_stat dtst; 356 357 memset(&dtst, 0, sizeof(dtst)); 358 if (ioctl(fd, DTIOCGSTATS, &dtst)) 359 warn("DTIOCGSTATS"); 360 361 printf("%llu events read\n", dtst.dtst_readevt); 362 printf("%llu events dropped\n", dtst.dtst_dropevt); 363 } 364 } 365 366 static inline enum dt_operand 367 dop2dt(enum bt_operand op) 368 { 369 switch (op) { 370 case B_OP_EQ: return DT_OP_EQ; 371 case B_OP_NE: return DT_OP_NE; 372 case B_OP_NONE: return DT_OP_NONE; 373 default: break; 374 } 375 xabort("unknown operand %d", op); 376 } 377 378 379 static inline enum dt_filtervar 380 dvar2dt(enum bt_filtervar var) 381 { 382 switch (var) { 383 case B_FV_PID: return DT_FV_PID; 384 case B_FV_TID: return DT_FV_TID; 385 case B_FV_NONE: return DT_FV_NONE; 386 default: break; 387 } 388 xabort("unknown filter %d", var); 389 } 390 391 392 void 393 rules_setup(int fd) 394 { 395 struct dtioc_probe_info *dtpi; 396 struct dtioc_req *dtrq; 397 struct bt_rule *r, *rbegin = NULL; 398 struct bt_probe *bp; 399 struct bt_stmt *bs; 400 int dokstack = 0, on = 1; 401 402 TAILQ_FOREACH(r, &g_rules, br_next) { 403 debug_dump_rule(r); 404 405 if (r->br_type != B_RT_PROBE) { 406 if (r->br_type == B_RT_BEGIN) 407 rbegin = r; 408 continue; 409 } 410 411 bp = r->br_probe; 412 dtpi_cache(fd); 413 dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func, bp->bp_name); 414 if (dtpi == NULL) 415 errx(1, "probe not found"); 416 417 dtrq = calloc(1, sizeof(*dtrq)); 418 if (dtrq == NULL) 419 err(1, "dtrq: 1alloc"); 420 421 r->br_pbn = dtpi->dtpi_pbn; 422 dtrq->dtrq_pbn = dtpi->dtpi_pbn; 423 if (r->br_filter) { 424 struct bt_filter *df = r->br_filter; 425 426 dtrq->dtrq_filter.dtf_operand = dop2dt(df->bf_op); 427 dtrq->dtrq_filter.dtf_variable = dvar2dt(df->bf_var); 428 dtrq->dtrq_filter.dtf_value = df->bf_val; 429 } 430 dtrq->dtrq_rate = r->br_probe->bp_rate; 431 432 SLIST_FOREACH(bs, &r->br_action, bs_next) { 433 struct bt_arg *ba; 434 435 SLIST_FOREACH(ba, &bs->bs_args, ba_next) { 436 switch (ba->ba_type) { 437 case B_AT_STR: 438 case B_AT_LONG: 439 case B_AT_VAR: 440 break; 441 case B_AT_BI_KSTACK: 442 dtrq->dtrq_evtflags |= DTEVT_KSTACK; 443 dokstack = 1; 444 break; 445 case B_AT_BI_USTACK: 446 dtrq->dtrq_evtflags |= DTEVT_USTACK; 447 break; 448 case B_AT_BI_COMM: 449 dtrq->dtrq_evtflags |= DTEVT_EXECNAME; 450 break; 451 case B_AT_BI_PID: 452 case B_AT_BI_TID: 453 case B_AT_BI_NSECS: 454 break; 455 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 456 dtrq->dtrq_evtflags |= DTEVT_FUNCARGS; 457 break; 458 case B_AT_BI_RETVAL: 459 dtrq->dtrq_evtflags |= DTEVT_RETVAL; 460 break; 461 case B_AT_MF_COUNT: 462 case B_AT_MF_MAX: 463 case B_AT_MF_MIN: 464 case B_AT_MF_SUM: 465 case B_AT_OP_ADD ... B_AT_OP_DIVIDE: 466 break; 467 default: 468 xabort("invalid argument type %d", 469 ba->ba_type); 470 } 471 } 472 } 473 474 r->br_cookie = dtrq; 475 } 476 477 if (dokstack) 478 kelf_open(); 479 480 if (rbegin) 481 rule_eval(rbegin, NULL); 482 483 /* Enable all probes */ 484 TAILQ_FOREACH(r, &g_rules, br_next) { 485 if (r->br_type != B_RT_PROBE) 486 continue; 487 488 dtrq = r->br_cookie; 489 if (ioctl(fd, DTIOCPRBENABLE, dtrq)) 490 err(1, "DTIOCPRBENABLE"); 491 } 492 493 if (g_nprobes > 0) { 494 if (ioctl(fd, DTIOCRECORD, &on)) 495 err(1, "DTIOCRECORD"); 496 } 497 } 498 499 void 500 rules_apply(struct dt_evt *dtev) 501 { 502 struct bt_rule *r; 503 504 TAILQ_FOREACH(r, &g_rules, br_next) { 505 if (r->br_type != B_RT_PROBE || r->br_pbn != dtev->dtev_pbn) 506 continue; 507 508 rule_eval(r, dtev); 509 } 510 } 511 512 void 513 rules_teardown(int fd) 514 { 515 struct dtioc_req *dtrq; 516 struct bt_rule *r, *rend = NULL; 517 int dokstack = 0, off = 0; 518 519 if (g_nprobes > 0) { 520 if (ioctl(fd, DTIOCRECORD, &off)) 521 err(1, "DTIOCRECORD"); 522 } 523 524 TAILQ_FOREACH(r, &g_rules, br_next) { 525 if (r->br_type != B_RT_PROBE) { 526 if (r->br_type == B_RT_END) 527 rend = r; 528 continue; 529 } 530 531 dtrq = r->br_cookie; 532 if (dtrq->dtrq_evtflags & DTEVT_KSTACK) 533 dokstack = 1; 534 } 535 536 if (dokstack) 537 kelf_close(); 538 539 if (rend) 540 rule_eval(rend, NULL); 541 } 542 543 void 544 rule_eval(struct bt_rule *r, struct dt_evt *dtev) 545 { 546 struct bt_stmt *bs; 547 548 debug("eval rule '%s'\n", debug_rule_name(r)); 549 550 SLIST_FOREACH(bs, &r->br_action, bs_next) { 551 switch (bs->bs_act) { 552 case B_AC_STORE: 553 stmt_store(bs, dtev); 554 break; 555 case B_AC_INSERT: 556 stmt_insert(bs, dtev); 557 break; 558 case B_AC_CLEAR: 559 stmt_clear(bs); 560 break; 561 case B_AC_DELETE: 562 stmt_delete(bs, dtev); 563 break; 564 case B_AC_EXIT: 565 exit(0); 566 break; 567 case B_AC_PRINT: 568 stmt_print(bs, dtev); 569 break; 570 case B_AC_PRINTF: 571 stmt_printf(bs, dtev); 572 break; 573 case B_AC_TIME: 574 stmt_time(bs, dtev); 575 break; 576 case B_AC_ZERO: 577 stmt_zero(bs); 578 break; 579 default: 580 xabort("no handler for action type %d", bs->bs_act); 581 } 582 } 583 } 584 585 time_t 586 builtin_gettime(struct dt_evt *dtev) 587 { 588 struct timespec ts; 589 590 if (dtev == NULL) { 591 clock_gettime(CLOCK_REALTIME, &ts); 592 return ts.tv_sec; 593 } 594 595 return dtev->dtev_tsp.tv_sec; 596 } 597 598 static inline uint64_t 599 TIMESPEC_TO_NSEC(struct timespec *ts) 600 { 601 return (ts->tv_sec * 1000000000L + ts->tv_nsec); 602 } 603 604 uint64_t 605 builtin_nsecs(struct dt_evt *dtev) 606 { 607 uint64_t nsecs; 608 609 if (dtev == NULL) { 610 struct timeval tv; 611 612 gettimeofday(&tv, NULL); 613 nsecs = (tv.tv_sec * 1000000000L + tv.tv_usec * 1000); 614 } else 615 nsecs = TIMESPEC_TO_NSEC(&dtev->dtev_tsp); 616 617 return nsecs; 618 } 619 620 #include <machine/vmparam.h> 621 #define INKERNEL(va) ((va) >= VM_MIN_KERNEL_ADDRESS) 622 623 const char * 624 builtin_stack(struct dt_evt *dtev, int kernel) 625 { 626 struct stacktrace *st = &dtev->dtev_kstack; 627 static char buf[4096]; 628 size_t i; 629 int n = 0; 630 631 if (st->st_count == 0) 632 return ""; 633 634 for (i = 0; i < st->st_count; i++) { 635 if (INKERNEL(st->st_pc[i])) { 636 if (!kernel) 637 continue; 638 n += kelf_snprintsym(buf + n, sizeof(buf) - 1 - n, 639 st->st_pc[i]); 640 } else if (!kernel) { 641 n += snprintf(buf + n, sizeof(buf) - 1 - n, "0x%lx\n", 642 st->st_pc[1]); 643 } 644 } 645 646 return buf; 647 } 648 649 const char * 650 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat) 651 { 652 static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */ 653 654 snprintf(buf, sizeof(buf) - 1, "%lu", dtev->dtev_sysargs[dat - B_AT_BI_ARG0]); 655 return buf; 656 } 657 658 void 659 stmt_clear(struct bt_stmt *bs) 660 { 661 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 662 struct bt_var *bv = ba->ba_value; 663 664 assert(bs->bs_var == NULL); 665 assert(ba->ba_type = B_AT_VAR); 666 667 map_clear(bv); 668 669 debug("map=%p '%s' clear\n", bv->bv_value, bv->bv_name); 670 } 671 672 /* 673 * Map delete: { delete(@map[key]); } 674 * 675 * In this case 'map' is represented by `bv' and 'key' by `bkey'. 676 */ 677 void 678 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev) 679 { 680 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 681 struct bt_var *bv = bmap->ba_value; 682 683 assert(bmap->ba_type == B_AT_MAP); 684 assert(bs->bs_var == NULL); 685 686 bkey = bmap->ba_key; 687 debug("map=%p '%s' delete key=%p\n", bv->bv_value, bv->bv_name, bkey); 688 689 map_delete(bv, ba2hash(bkey, dtev)); 690 } 691 692 /* 693 * Map insert: { @map[key] = 42; } 694 * 695 * In this case 'map' is represented by `bv', 'key' by `bkey' and 696 * '42' by `bval'. 697 */ 698 void 699 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev) 700 { 701 struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args); 702 struct bt_arg *bval = (struct bt_arg *)bs->bs_var; 703 struct bt_var *bv = bmap->ba_value; 704 705 assert(bmap->ba_type == B_AT_MAP); 706 assert(SLIST_NEXT(bval, ba_next) == NULL); 707 708 bkey = bmap->ba_key; 709 debug("map=%p '%s' insert key=%p bval=%p\n", bv->bv_value, bv->bv_name, 710 bkey, bval); 711 712 map_insert(bv, ba2hash(bkey, dtev), bval); 713 } 714 715 /* 716 * Print map entries: { print(@map[, 8]); } 717 * 718 * In this case the global variable 'map' is pointed at by `ba' 719 * and '8' is represented by `btop'. 720 */ 721 void 722 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev) 723 { 724 struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args); 725 struct bt_var *bv = ba->ba_value; 726 size_t top = SIZE_T_MAX; 727 728 assert(bs->bs_var == NULL); 729 assert(ba->ba_type = B_AT_VAR); 730 731 /* Parse optional `top' argument. */ 732 btop = SLIST_NEXT(ba, ba_next); 733 if (btop != NULL) { 734 assert(SLIST_NEXT(btop, ba_next) == NULL); 735 top = ba2long(btop, dtev); 736 } 737 738 map_print(bv, top); 739 740 debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv->bv_name, top); 741 } 742 743 /* 744 * Variable store: { var = 3; } 745 * 746 * In this case '3' is represented by `ba', the argument of a STORE 747 * action. 748 * 749 * If the argument depends of the value of an event (builtin) or is 750 * the result of an operation, its evaluation is stored in a new `ba'. 751 */ 752 void 753 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev) 754 { 755 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 756 struct bt_var *bv = bs->bs_var; 757 758 assert(SLIST_NEXT(ba, ba_next) == NULL); 759 760 switch (ba->ba_type) { 761 case B_AT_LONG: 762 bv->bv_value = ba; 763 break; 764 case B_AT_BI_NSECS: 765 bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG); 766 break; 767 case B_AT_OP_ADD ... B_AT_OP_DIVIDE: 768 bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG); 769 break; 770 default: 771 xabort("store not implemented for type %d", ba->ba_type); 772 } 773 774 debug("bv=%p var '%s' store (%p) \n", bv, bv->bv_name, bv->bv_value); 775 } 776 777 /* 778 * Print time: { time("%H:%M:%S"); } 779 */ 780 void 781 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev) 782 { 783 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 784 time_t time; 785 struct tm *tm; 786 char buf[64]; 787 788 assert(bs->bs_var == NULL); 789 assert(ba->ba_type = B_AT_STR); 790 assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1)); 791 792 time = builtin_gettime(dtev); 793 tm = localtime(&time); 794 strftime(buf, sizeof(buf), ba2str(ba, dtev), tm); 795 printf("%s", buf); 796 } 797 798 void 799 stmt_zero(struct bt_stmt *bs) 800 { 801 struct bt_arg *ba = SLIST_FIRST(&bs->bs_args); 802 struct bt_var *bv = ba->ba_value; 803 804 assert(bs->bs_var == NULL); 805 assert(ba->ba_type = B_AT_VAR); 806 807 map_zero(bv); 808 809 debug("map=%p '%s' zero\n", bv->bv_value, bv->bv_name); 810 } 811 812 struct bt_arg * 813 ba_read(struct bt_arg *ba) 814 { 815 struct bt_var *bv = ba->ba_value; 816 817 assert(ba->ba_type == B_AT_VAR); 818 819 debug("bv=%p read '%s' (%p)\n", bv, bv->bv_name, bv->bv_value); 820 821 return bv->bv_value; 822 } 823 824 /* 825 * Helper to evaluate the operation encoded in `ba' and return its 826 * result. 827 */ 828 static inline long 829 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev) 830 { 831 static long recursions; 832 struct bt_arg *a, *b; 833 long first, second, result; 834 835 if (++recursions >= __MAXOPERANDS) 836 errx(1, "too many operands (>%d) in expression", __MAXOPERANDS); 837 838 a = ba->ba_value; 839 b = SLIST_NEXT(a, ba_next); 840 841 assert(SLIST_NEXT(b, ba_next) == NULL); 842 843 first = ba2long(a, dtev); 844 second = ba2long(b, dtev); 845 846 switch (ba->ba_type) { 847 case B_AT_OP_ADD: 848 result = first + second; 849 break; 850 case B_AT_OP_MINUS: 851 result = first - second; 852 break; 853 case B_AT_OP_MULT: 854 result = first * second; 855 break; 856 case B_AT_OP_DIVIDE: 857 result = first / second; 858 break; 859 default: 860 xabort("unsuported operation %d", ba->ba_type); 861 } 862 863 debug("ba=%p (%ld op %ld) = %ld\n", ba, first, second, result); 864 865 --recursions; 866 867 return result; 868 } 869 870 /* 871 * Return the representation of `ba' as long. 872 */ 873 long 874 ba2long(struct bt_arg *ba, struct dt_evt *dtev) 875 { 876 long val; 877 878 switch (ba->ba_type) { 879 case B_AT_LONG: 880 val = (long)ba->ba_value; 881 break; 882 case B_AT_VAR: 883 ba = ba_read(ba); 884 val = (long)ba->ba_value; 885 break; 886 case B_AT_BI_NSECS: 887 val = builtin_nsecs(dtev); 888 break; 889 case B_AT_OP_ADD ... B_AT_OP_DIVIDE: 890 val = baexpr2long(ba, dtev); 891 break; 892 default: 893 xabort("no long conversion for type %d", ba->ba_type); 894 } 895 896 debug("ba=%p long='%ld'\n", ba, val); 897 898 return val; 899 } 900 901 /* 902 * Return the representation of `ba' as string. 903 */ 904 const char * 905 ba2str(struct bt_arg *ba, struct dt_evt *dtev) 906 { 907 static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */ 908 const char *str; 909 910 switch (ba->ba_type) { 911 case B_AT_STR: 912 str = (const char *)ba->ba_value; 913 break; 914 case B_AT_LONG: 915 snprintf(buf, sizeof(buf) - 1, "%ld",(long)ba->ba_value); 916 str = buf; 917 break; 918 case B_AT_BI_KSTACK: 919 str = builtin_stack(dtev, 1); 920 break; 921 case B_AT_BI_USTACK: 922 str = builtin_stack(dtev, 0); 923 break; 924 case B_AT_BI_COMM: 925 str = dtev->dtev_comm; 926 break; 927 case B_AT_BI_PID: 928 snprintf(buf, sizeof(buf) - 1, "%d", dtev->dtev_pid); 929 str = buf; 930 break; 931 case B_AT_BI_TID: 932 snprintf(buf, sizeof(buf) - 1, "%d", dtev->dtev_tid); 933 str = buf; 934 break; 935 case B_AT_BI_NSECS: 936 snprintf(buf, sizeof(buf) - 1, "%llu", builtin_nsecs(dtev)); 937 str = buf; 938 break; 939 case B_AT_BI_ARG0 ... B_AT_BI_ARG9: 940 str = builtin_arg(dtev, ba->ba_type); 941 break; 942 case B_AT_BI_RETVAL: 943 snprintf(buf, sizeof(buf) - 1, "%ld", (long)dtev->dtev_sysretval); 944 str = buf; 945 break; 946 case B_AT_MAP: 947 str = ba2str(map_get(ba->ba_value, ba2str(ba->ba_key, dtev)), dtev); 948 break; 949 case B_AT_VAR: 950 str = ba2str(ba_read(ba), dtev); 951 break; 952 case B_AT_OP_ADD ... B_AT_OP_DIVIDE: 953 snprintf(buf, sizeof(buf) - 1, "%ld", ba2long(ba, dtev)); 954 str = buf; 955 break; 956 case B_AT_MF_COUNT: 957 case B_AT_MF_MAX: 958 case B_AT_MF_MIN: 959 case B_AT_MF_SUM: 960 assert(0); 961 break; 962 default: 963 xabort("no string conversion for type %d", ba->ba_type); 964 } 965 966 debug("ba=%p str='%s'\n", ba, str); 967 968 return str; 969 } 970 971 long 972 bacmp(struct bt_arg *a, struct bt_arg *b) 973 { 974 assert(a->ba_type == b->ba_type); 975 assert(a->ba_type == B_AT_LONG); 976 977 return ba2long(a, NULL) - ba2long(b, NULL); 978 } 979 980 __dead void 981 xabort(const char *fmt, ...) 982 { 983 va_list ap; 984 985 va_start(ap, fmt); 986 vfprintf(stderr, fmt, ap); 987 va_end(ap); 988 989 fprintf(stderr, "\n"); 990 abort(); 991 } 992 993 void 994 debug(const char *fmt, ...) 995 { 996 va_list ap; 997 998 if (verbose < 2) 999 return; 1000 1001 fprintf(stderr, "debug: "); 1002 1003 va_start(ap, fmt); 1004 vfprintf(stderr, fmt, ap); 1005 va_end(ap); 1006 } 1007 1008 void 1009 debugx(const char *fmt, ...) 1010 { 1011 va_list ap; 1012 1013 if (verbose < 2) 1014 return; 1015 1016 va_start(ap, fmt); 1017 vfprintf(stderr, fmt, ap); 1018 va_end(ap); 1019 } 1020 1021 static inline const char * 1022 debug_getfiltervar(struct bt_filter *df) 1023 { 1024 switch (df->bf_var) { 1025 case B_FV_PID: return "pid"; 1026 case B_FV_TID: return "tid"; 1027 case B_FV_NONE: return ""; 1028 default: 1029 xabort("invalid filtervar %d", df->bf_var); 1030 } 1031 1032 1033 } 1034 1035 static inline const char * 1036 debug_getfilterop(struct bt_filter *df) 1037 { 1038 switch (df->bf_op) { 1039 case B_OP_EQ: return "=="; 1040 case B_OP_NE: return "!="; 1041 case B_OP_NONE: return ""; 1042 default: 1043 xabort("invalid operand %d", df->bf_op); 1044 } 1045 } 1046 1047 void 1048 debug_dump_filter(struct bt_rule *r) 1049 { 1050 if (r->br_filter) { 1051 debugx(" / %s %s %u /", debug_getfiltervar(r->br_filter), 1052 debug_getfilterop(r->br_filter), r->br_filter->bf_val); 1053 } 1054 debugx("\n"); 1055 } 1056 1057 const char * 1058 debug_rule_name(struct bt_rule *r) 1059 { 1060 struct bt_probe *bp = r->br_probe; 1061 static char buf[64]; 1062 1063 if (r->br_type == B_RT_BEGIN) 1064 return "BEGIN"; 1065 1066 if (r->br_type == B_RT_END) 1067 return "END"; 1068 1069 assert(r->br_type == B_RT_PROBE); 1070 1071 if (r->br_probe->bp_rate) { 1072 snprintf(buf, sizeof(buf) - 1, "%s:%s:%u", bp->bp_prov, 1073 bp->bp_unit, bp->bp_rate); 1074 } else { 1075 snprintf(buf, sizeof(buf) - 1, "%s:%s:%s", bp->bp_prov, 1076 bp->bp_unit, bp->bp_name); 1077 } 1078 1079 return buf; 1080 } 1081 1082 void 1083 debug_dump_rule(struct bt_rule *r) 1084 { 1085 debug("parsed probe '%s'", debug_rule_name(r)); 1086 debug_dump_filter(r); 1087 } 1088