1 /*- 2 * Copyright (c) 2002 Jake Burkholder 3 * Copyright (c) 2004 Robert Watson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: src/usr.bin/ktrdump/ktrdump.c,v 1.10 2005/05/21 09:55:06 ru Exp $ 28 */ 29 30 #include <sys/types.h> 31 #include <sys/ktr.h> 32 #include <sys/mman.h> 33 #include <sys/stat.h> 34 #include <sys/queue.h> 35 36 #include <ctype.h> 37 #include <devinfo.h> 38 #include <err.h> 39 #include <fcntl.h> 40 #include <kvm.h> 41 #include <limits.h> 42 #include <nlist.h> 43 #include <stddef.h> 44 #include <stdint.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 #include <evtr.h> 50 #include <stdarg.h> 51 52 struct ktr_buffer { 53 struct ktr_entry *ents; 54 int modified; 55 int reset; 56 int beg_idx; /* Beginning index */ 57 int end_idx; /* Ending index */ 58 }; 59 60 static struct nlist nl1[] = { 61 { .n_name = "_ktr_version" }, 62 { .n_name = "_ktr_entries" }, 63 { .n_name = "_ncpus" }, 64 { .n_name = NULL } 65 }; 66 67 static struct nlist nl2[] = { 68 { .n_name = "_tsc_frequency" }, 69 { .n_name = NULL } 70 }; 71 72 static struct nlist nl_version_ktr_idx[] = { 73 { .n_name = "_ktr_idx" }, 74 { .n_name = "_ktr_buf" }, 75 { .n_name = NULL } 76 }; 77 78 static struct nlist nl_version_ktr_cpu[] = { 79 { .n_name = "_ktr_cpu" }, 80 { .n_name = NULL } 81 }; 82 83 struct save_ctx { 84 char save_buf[512]; 85 const void *save_kptr; 86 }; 87 88 typedef void (*ktr_iter_cb_t)(void *, int, int, struct ktr_entry *, uint64_t *); 89 90 #ifdef __x86_64__ 91 /* defined according to the x86_64 ABI spec */ 92 struct my_va_list { 93 uint32_t gp_offset; /* offset to next available gpr in reg_save_area */ 94 uint32_t fp_offset; /* offset to next available fpr in reg_save_area */ 95 void *overflow_arg_area; /* args that are passed on the stack */ 96 struct reg_save_area *reg_save_area; /* register args */ 97 /* 98 * NOT part of the ABI. ->overflow_arg_area gets advanced when code 99 * iterates over the arguments with va_arg(). That means we need to 100 * keep a copy in order to free the allocated memory (if any) 101 */ 102 void *overflow_arg_area_save; 103 } __attribute__((packed)); 104 105 typedef struct my_va_list *machine_va_list; 106 107 struct reg_save_area { 108 uint64_t rdi, rsi, rdx, rcx, r8, r9; 109 /* XMM registers follow, but we don't use them */ 110 }; 111 #endif 112 113 static int cflag; 114 static int dflag; 115 static int fflag; 116 static int iflag; 117 static int lflag; 118 static int nflag; 119 static int qflag; 120 static int rflag; 121 static int sflag; 122 static int tflag; 123 static int xflag; 124 static int pflag; 125 static int Mflag; 126 static int Nflag; 127 static double tsc_frequency; 128 static double correction_factor = 0.0; 129 130 static char corefile[PATH_MAX]; 131 static char execfile[PATH_MAX]; 132 133 static char errbuf[_POSIX2_LINE_MAX]; 134 static int ncpus; 135 static kvm_t *kd; 136 static int entries_per_buf; 137 static int fifo_mask; 138 static int ktr_version; 139 140 static void usage(void); 141 static int earliest_ts(struct ktr_buffer *); 142 static void dump_machine_info(evtr_t); 143 static void dump_device_info(evtr_t); 144 static void print_header(FILE *, int); 145 static void print_entry(FILE *, int, int, struct ktr_entry *, u_int64_t *); 146 static void print_callback(void *, int, int, struct ktr_entry *, uint64_t *); 147 static void dump_callback(void *, int, int, struct ktr_entry *, uint64_t *); 148 static struct ktr_info *kvm_ktrinfo(void *, struct save_ctx *); 149 static const char *kvm_string(const char *, struct save_ctx *); 150 static const char *trunc_path(const char *, int); 151 static void read_symbols(const char *); 152 static const char *address_to_symbol(void *, struct save_ctx *); 153 static struct ktr_buffer *ktr_bufs_init(void); 154 static void get_indices(struct ktr_entry **, int *); 155 static void load_bufs(struct ktr_buffer *, struct ktr_entry **, int *); 156 static void iterate_buf(FILE *, struct ktr_buffer *, int, u_int64_t *, ktr_iter_cb_t); 157 static void iterate_bufs_timesorted(FILE *, struct ktr_buffer *, u_int64_t *, ktr_iter_cb_t); 158 static void kvmfprintf(FILE *fp, const char *ctl, va_list va); 159 static int va_list_from_blob(machine_va_list *valist, const char *fmt, char *blob, size_t blobsize); 160 static void va_list_cleanup(machine_va_list *valist); 161 /* 162 * Reads the ktr trace buffer from kernel memory and prints the trace entries. 163 */ 164 int 165 main(int ac, char **av) 166 { 167 struct ktr_buffer *ktr_bufs; 168 struct ktr_entry **ktr_kbuf; 169 ktr_iter_cb_t callback = &print_callback; 170 int *ktr_idx; 171 FILE *fo; 172 void *ctx; 173 int64_t tts; 174 int *ktr_start_index; 175 int c; 176 int n; 177 178 /* 179 * Parse commandline arguments. 180 */ 181 fo = stdout; 182 while ((c = getopt(ac, av, "acfinqrtxpslA:N:M:o:d")) != -1) { 183 switch (c) { 184 case 'a': 185 cflag = 1; 186 iflag = 1; 187 rflag = 1; 188 xflag = 1; 189 pflag = 1; 190 sflag = 1; 191 break; 192 case 'c': 193 cflag = 1; 194 break; 195 case 'd': 196 dflag = 1; 197 sflag = 1; 198 callback = &dump_callback; 199 break; 200 case 'N': 201 if (strlcpy(execfile, optarg, sizeof(execfile)) 202 >= sizeof(execfile)) 203 errx(1, "%s: File name too long", optarg); 204 Nflag = 1; 205 break; 206 case 'f': 207 fflag = 1; 208 break; 209 case 'l': 210 lflag = 1; 211 break; 212 case 'i': 213 iflag = 1; 214 break; 215 case 'A': 216 correction_factor = strtod(optarg, NULL); 217 break; 218 case 'M': 219 if (strlcpy(corefile, optarg, sizeof(corefile)) 220 >= sizeof(corefile)) 221 errx(1, "%s: File name too long", optarg); 222 Mflag = 1; 223 break; 224 case 'n': 225 nflag = 1; 226 break; 227 case 'o': 228 if ((fo = fopen(optarg, "w")) == NULL) 229 err(1, "%s", optarg); 230 break; 231 case 'p': 232 pflag++; 233 break; 234 case 'q': 235 qflag++; 236 break; 237 case 'r': 238 rflag = 1; 239 break; 240 case 's': 241 sflag = 1; /* sort across the cpus */ 242 break; 243 case 't': 244 tflag = 1; 245 break; 246 case 'x': 247 xflag = 1; 248 break; 249 case '?': 250 default: 251 usage(); 252 } 253 } 254 ctx = fo; 255 if (dflag) { 256 ctx = evtr_open_write(fo); 257 if (!ctx) { 258 err(1, "Can't create event stream"); 259 } 260 } 261 if (cflag + iflag + tflag + xflag + fflag + pflag == 0) { 262 cflag = 1; 263 iflag = 1; 264 tflag = 1; 265 pflag = 1; 266 } 267 if (correction_factor != 0.0 && (rflag == 0 || nflag)) { 268 fprintf(stderr, "Correction factor can only be applied with -r and without -n\n"); 269 exit(1); 270 } 271 ac -= optind; 272 av += optind; 273 if (ac != 0) 274 usage(); 275 276 /* 277 * Open our execfile and corefile, resolve needed symbols and read in 278 * the trace buffer. 279 */ 280 if ((kd = kvm_openfiles(Nflag ? execfile : NULL, 281 Mflag ? corefile : NULL, NULL, O_RDONLY, errbuf)) == NULL) 282 errx(1, "%s", errbuf); 283 if (kvm_nlist(kd, nl1) != 0) 284 errx(1, "%s", kvm_geterr(kd)); 285 if (kvm_read(kd, nl1[0].n_value, &ktr_version, sizeof(ktr_version)) == -1) 286 errx(1, "%s", kvm_geterr(kd)); 287 if (kvm_read(kd, nl1[2].n_value, &ncpus, sizeof(ncpus)) == -1) 288 errx(1, "%s", kvm_geterr(kd)); 289 ktr_start_index = malloc(sizeof(*ktr_start_index) * ncpus); 290 if (ktr_version >= KTR_VERSION_WITH_FREQ && kvm_nlist(kd, nl2) == 0) { 291 if (kvm_read(kd, nl2[0].n_value, &tts, sizeof(tts)) == -1) 292 errx(1, "%s", kvm_geterr(kd)); 293 tsc_frequency = (double)tts; 294 } 295 if (ktr_version > KTR_VERSION) 296 errx(1, "ktr version too high for us to handle"); 297 if (kvm_read(kd, nl1[1].n_value, &entries_per_buf, 298 sizeof(entries_per_buf)) == -1) 299 errx(1, "%s", kvm_geterr(kd)); 300 fifo_mask = entries_per_buf - 1; 301 302 printf("TSC frequency is %6.3f MHz\n", tsc_frequency / 1000000.0); 303 304 if (dflag) { 305 dump_machine_info((evtr_t)ctx); 306 dump_device_info((evtr_t)ctx); 307 } 308 ktr_kbuf = calloc(ncpus, sizeof(*ktr_kbuf)); 309 ktr_idx = calloc(ncpus, sizeof(*ktr_idx)); 310 311 if (nflag == 0) 312 read_symbols(Nflag ? execfile : NULL); 313 314 if (ktr_version < KTR_VERSION_KTR_CPU) { 315 if (kvm_nlist(kd, nl_version_ktr_idx)) 316 errx(1, "%s", kvm_geterr(kd)); 317 } else { 318 if (kvm_nlist(kd, nl_version_ktr_cpu)) 319 errx(1, "%s", kvm_geterr(kd)); 320 } 321 322 get_indices(ktr_kbuf, ktr_idx); 323 324 ktr_bufs = ktr_bufs_init(); 325 326 if (sflag) { 327 u_int64_t last_timestamp = 0; 328 do { 329 load_bufs(ktr_bufs, ktr_kbuf, ktr_idx); 330 iterate_bufs_timesorted(ctx, ktr_bufs, &last_timestamp, 331 callback); 332 if (lflag) 333 usleep(1000000 / 10); 334 } while (lflag); 335 } else { 336 u_int64_t *last_timestamp = calloc(sizeof(u_int64_t), ncpus); 337 do { 338 load_bufs(ktr_bufs, ktr_kbuf, ktr_idx); 339 for (n = 0; n < ncpus; ++n) 340 iterate_buf(ctx, ktr_bufs, n, &last_timestamp[n], 341 callback); 342 if (lflag) 343 usleep(1000000 / 10); 344 } while (lflag); 345 } 346 if (dflag) 347 evtr_close(ctx); 348 return (0); 349 } 350 351 static 352 int 353 dump_devinfo(struct devinfo_dev *dev, void *arg) 354 { 355 struct evtr_event ev; 356 evtr_t evtr = (evtr_t)arg; 357 const char *fmt = "#devicenames[\"%s\"] = %#lx"; 358 char fmtdatabuf[sizeof(char *) + sizeof(devinfo_handle_t)]; 359 char *fmtdata = fmtdatabuf; 360 361 if (!dev->dd_name[0]) 362 return 0; 363 ev.type = EVTR_TYPE_PROBE; 364 ev.ts = 0; 365 ev.line = 0; 366 ev.file = NULL; 367 ev.cpu = -1; 368 ev.func = NULL; 369 ev.fmt = fmt; 370 ((char **)fmtdata)[0] = &dev->dd_name[0]; 371 fmtdata += sizeof(char *); 372 ((devinfo_handle_t *)fmtdata)[0] = dev->dd_handle; 373 ev.fmtdata = fmtdatabuf; 374 ev.fmtdatalen = sizeof(fmtdatabuf); 375 376 if (evtr_dump_event(evtr, &ev)) { 377 err(1, "%s", evtr_errmsg(evtr)); 378 } 379 380 return devinfo_foreach_device_child(dev, dump_devinfo, evtr); 381 } 382 383 static 384 void 385 dump_device_info(evtr_t evtr) 386 { 387 struct devinfo_dev *root; 388 if (devinfo_init()) 389 return; 390 if (!(root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE))) { 391 warn("can't find root device"); 392 return; 393 } 394 devinfo_foreach_device_child(root, dump_devinfo, evtr); 395 } 396 397 static 398 void 399 dump_machine_info(evtr_t evtr) 400 { 401 struct evtr_event ev; 402 int i; 403 404 bzero(&ev, sizeof(ev)); 405 ev.type = EVTR_TYPE_SYSINFO; 406 ev.ncpus = ncpus; 407 evtr_dump_event(evtr, &ev); 408 if (evtr_error(evtr)) { 409 err(1, "%s", evtr_errmsg(evtr)); 410 } 411 412 for (i = 0; i < ncpus; ++i) { 413 bzero(&ev, sizeof(ev)); 414 ev.type = EVTR_TYPE_CPUINFO; 415 ev.cpu = i; 416 ev.cpuinfo.freq = tsc_frequency; 417 evtr_dump_event(evtr, &ev); 418 if (evtr_error(evtr)) { 419 err(1, "%s", evtr_errmsg(evtr)); 420 } 421 } 422 } 423 424 static void 425 print_header(FILE *fo, int row) 426 { 427 if (qflag == 0 && (u_int32_t)row % 20 == 0) { 428 fprintf(fo, "%-6s ", "index"); 429 if (cflag) 430 fprintf(fo, "%-3s ", "cpu"); 431 if (tflag || rflag) 432 fprintf(fo, "%-16s ", "timestamp"); 433 if (xflag) { 434 if (nflag) 435 fprintf(fo, "%-18s %-18s ", "caller2", "caller1"); 436 else 437 fprintf(fo, "%-25s %-25s ", "caller2", "caller1"); 438 } 439 if (iflag) 440 fprintf(fo, "%-20s ", "ID"); 441 if (fflag) 442 fprintf(fo, "%10s%-30s", "", "file and line"); 443 if (pflag) 444 fprintf(fo, "%s", "trace"); 445 fprintf(fo, "\n"); 446 } 447 } 448 449 static void 450 print_entry(FILE *fo, int n, int row, struct ktr_entry *entry, 451 u_int64_t *last_timestamp) 452 { 453 struct ktr_info *info = NULL; 454 static struct save_ctx nctx, pctx, fmtctx, symctx, infoctx; 455 456 fprintf(fo, "%06x ", row & 0x00FFFFFF); 457 if (cflag) 458 fprintf(fo, "%-3d ", n); 459 if (tflag || rflag) { 460 if (rflag && !nflag && tsc_frequency != 0.0) { 461 fprintf(fo, "%13.3f uS ", 462 (double)(entry->ktr_timestamp - *last_timestamp) * 1000000.0 / tsc_frequency - correction_factor); 463 } else if (rflag) { 464 fprintf(fo, "%-16ju ", 465 (uintmax_t)(entry->ktr_timestamp - *last_timestamp)); 466 } else { 467 fprintf(fo, "%-16ju ", 468 (uintmax_t)entry->ktr_timestamp); 469 } 470 } 471 if (xflag) { 472 if (nflag) { 473 fprintf(fo, "%p %p ", 474 entry->ktr_caller2, entry->ktr_caller1); 475 } else { 476 fprintf(fo, "%-25s ", 477 address_to_symbol(entry->ktr_caller2, &symctx)); 478 fprintf(fo, "%-25s ", 479 address_to_symbol(entry->ktr_caller1, &symctx)); 480 } 481 } 482 if (iflag) { 483 info = kvm_ktrinfo(entry->ktr_info, &infoctx); 484 if (info) 485 fprintf(fo, "%-20s ", kvm_string(info->kf_name, &nctx)); 486 else 487 fprintf(fo, "%-20s ", "<empty>"); 488 } 489 if (fflag) 490 fprintf(fo, "%34s:%-4d ", 491 trunc_path(kvm_string(entry->ktr_file, &pctx), 34), 492 entry->ktr_line); 493 if (pflag) { 494 if (info == NULL) 495 info = kvm_ktrinfo(entry->ktr_info, &infoctx); 496 if (info) { 497 machine_va_list ap; 498 const char *fmt; 499 fmt = kvm_string(info->kf_format, &fmtctx); 500 if (va_list_from_blob(&ap, fmt, 501 (char *)&entry->ktr_data, 502 info->kf_data_size)) 503 err(2, "Can't generate va_list from %s", fmt); 504 kvmfprintf(fo, kvm_string(info->kf_format, &fmtctx), 505 (void *)ap); 506 va_list_cleanup(&ap); 507 } 508 } 509 fprintf(fo, "\n"); 510 *last_timestamp = entry->ktr_timestamp; 511 } 512 513 static 514 void 515 print_callback(void *ctx, int n, int row, struct ktr_entry *entry, uint64_t *last_ts) 516 { 517 FILE *fo = (FILE *)ctx; 518 print_header(fo, row); 519 print_entry(fo, n, row, entry, last_ts); 520 } 521 522 /* 523 * If free == 0, replace all (kvm) string pointers in fmtdata with pointers 524 * to user-allocated copies of the strings. 525 * If free != 0, free those pointers. 526 */ 527 static 528 int 529 mangle_string_ptrs(const char *fmt, uint8_t *fmtdata, int dofree) 530 { 531 const char *f, *p; 532 size_t skipsize, intsz; 533 static struct save_ctx strctx; 534 int ret = 0; 535 536 for (f = fmt; f[0] != '\0'; ++f) { 537 if (f[0] != '%') 538 continue; 539 ++f; 540 skipsize = 0; 541 for (p = f; p[0]; ++p) { 542 int again = 0; 543 /* 544 * Eat flags. Notice this will accept duplicate 545 * flags. 546 */ 547 switch (p[0]) { 548 case '#': 549 case '0': 550 case '-': 551 case ' ': 552 case '+': 553 case '\'': 554 again = !0; 555 break; 556 } 557 if (!again) 558 break; 559 } 560 /* Eat minimum field width, if any */ 561 for (; isdigit(p[0]); ++p) 562 ; 563 if (p[0] == '.') 564 ++p; 565 /* Eat precision, if any */ 566 for (; isdigit(p[0]); ++p) 567 ; 568 intsz = 0; 569 switch (p[0]) { 570 case 'h': 571 if (p[1] == 'h') { 572 ++p; 573 intsz = sizeof(char); 574 } else { 575 intsz = sizeof(short); 576 } 577 break; 578 case 'l': 579 if (p[1] == 'l') { 580 ++p; 581 intsz = sizeof(long long); 582 } else { 583 intsz = sizeof(long); 584 } 585 break; 586 case 'j': 587 intsz = sizeof(intmax_t); 588 break; 589 case 't': 590 intsz = sizeof(ptrdiff_t); 591 break; 592 case 'z': 593 intsz = sizeof(size_t); 594 break; 595 default: 596 break; 597 } 598 if (intsz != 0) 599 ++p; 600 else 601 intsz = sizeof(int); 602 603 switch (p[0]) { 604 case 'd': 605 case 'i': 606 case 'o': 607 case 'u': 608 case 'x': 609 case 'X': 610 case 'c': 611 skipsize = intsz; 612 break; 613 case 'p': 614 skipsize = sizeof(void *); 615 break; 616 case 'f': 617 if (p[-1] == 'l') 618 skipsize = sizeof(double); 619 else 620 skipsize = sizeof(float); 621 break; 622 case 's': 623 if (dofree) { 624 char *t = ((char **)fmtdata)[0]; 625 free(t); 626 skipsize = sizeof(char *); 627 } else { 628 char *t = strdup(kvm_string(((char **)fmtdata)[0], 629 &strctx)); 630 ((const char **)fmtdata)[0] = t; 631 632 skipsize = sizeof(char *); 633 } 634 ++ret; 635 break; 636 default: 637 fprintf(stderr, "Unknown conversion specifier %c " 638 "in fmt starting with %s\n", p[0], f - 1); 639 return -1; 640 } 641 fmtdata += skipsize; 642 } 643 return ret; 644 } 645 646 static 647 void 648 dump_callback(void *ctx, int n, int row __unused, struct ktr_entry *entry, 649 uint64_t *last_ts __unused) 650 { 651 evtr_t evtr = (evtr_t)ctx; 652 struct evtr_event ev; 653 static struct save_ctx pctx, fmtctx, infoctx; 654 struct ktr_info *ki; 655 int conv = 0; /* pointless */ 656 657 ev.ts = entry->ktr_timestamp; 658 ev.type = EVTR_TYPE_PROBE; 659 ev.line = entry->ktr_line; 660 ev.file = kvm_string(entry->ktr_file, &pctx); 661 ev.func = NULL; 662 ev.cpu = n; 663 if ((ki = kvm_ktrinfo(entry->ktr_info, &infoctx))) { 664 ev.fmt = kvm_string(ki->kf_format, &fmtctx); 665 ev.fmtdata = entry->ktr_data; 666 if ((conv = mangle_string_ptrs(ev.fmt, 667 __DECONST(uint8_t *, ev.fmtdata), 668 0)) < 0) 669 errx(1, "Can't parse format string"); 670 ev.fmtdatalen = ki->kf_data_size; 671 } else { 672 ev.fmt = ev.fmtdata = NULL; 673 ev.fmtdatalen = 0; 674 } 675 if (evtr_dump_event(evtr, &ev)) { 676 err(1, "%s", evtr_errmsg(evtr)); 677 } 678 if (ev.fmtdata && conv) { 679 mangle_string_ptrs(ev.fmt, __DECONST(uint8_t *, ev.fmtdata), 680 !0); 681 } 682 } 683 684 static 685 struct ktr_info * 686 kvm_ktrinfo(void *kptr, struct save_ctx *ctx) 687 { 688 struct ktr_info *ki = (void *)ctx->save_buf; 689 690 if (kptr == NULL) 691 return(NULL); 692 if (ctx->save_kptr != kptr) { 693 if (kvm_read(kd, (uintptr_t)kptr, ki, sizeof(*ki)) == -1) { 694 bzero(ki, sizeof(*ki)); 695 } else { 696 ctx->save_kptr = kptr; 697 } 698 } 699 return(ki); 700 } 701 702 static 703 const char * 704 kvm_string(const char *kptr, struct save_ctx *ctx) 705 { 706 u_int l; 707 u_int n; 708 709 if (kptr == NULL) 710 return("?"); 711 if (ctx->save_kptr != (const void *)kptr) { 712 ctx->save_kptr = (const void *)kptr; 713 l = 0; 714 while (l < sizeof(ctx->save_buf) - 1) { 715 n = 256 - ((intptr_t)(kptr + l) & 255); 716 if (n > sizeof(ctx->save_buf) - l - 1) 717 n = sizeof(ctx->save_buf) - l - 1; 718 if (kvm_read(kd, (uintptr_t)(kptr + l), ctx->save_buf + l, n) < 0) 719 break; 720 while (l < sizeof(ctx->save_buf) && n) { 721 if (ctx->save_buf[l] == 0) 722 break; 723 --n; 724 ++l; 725 } 726 if (n) 727 break; 728 } 729 ctx->save_buf[l] = 0; 730 } 731 return(ctx->save_buf); 732 } 733 734 static 735 const char * 736 trunc_path(const char *str, int maxlen) 737 { 738 int len = strlen(str); 739 740 if (len > maxlen) 741 return(str + len - maxlen); 742 else 743 return(str); 744 } 745 746 struct symdata { 747 TAILQ_ENTRY(symdata) link; 748 const char *symname; 749 char *symaddr; 750 char symtype; 751 }; 752 753 static TAILQ_HEAD(symlist, symdata) symlist; 754 static struct symdata *symcache; 755 static char *symbegin; 756 static char *symend; 757 758 static 759 void 760 read_symbols(const char *file) 761 { 762 char buf[256]; 763 char cmd[256]; 764 size_t buflen = sizeof(buf); 765 FILE *fp; 766 struct symdata *sym = NULL; 767 char *s1; 768 char *s2; 769 char *s3; 770 771 TAILQ_INIT(&symlist); 772 773 if (file == NULL) { 774 if (sysctlbyname("kern.bootfile", buf, &buflen, NULL, 0) < 0) 775 file = "/boot/kernel/kernel"; 776 else 777 file = buf; 778 } 779 snprintf(cmd, sizeof(cmd), "nm -n %s", file); 780 if ((fp = popen(cmd, "r")) != NULL) { 781 while (fgets(buf, sizeof(buf), fp) != NULL) { 782 s1 = strtok(buf, " \t\n"); 783 s2 = strtok(NULL, " \t\n"); 784 s3 = strtok(NULL, " \t\n"); 785 if (s1 && s2 && s3) { 786 sym = malloc(sizeof(struct symdata)); 787 sym->symaddr = (char *)strtoul(s1, NULL, 16); 788 sym->symtype = s2[0]; 789 sym->symname = strdup(s3); 790 if (strcmp(s3, "kernbase") == 0) 791 symbegin = sym->symaddr; 792 if (strcmp(s3, "end") == 0 || strcmp(s3, "_end") == 0) 793 symend = sym->symaddr; 794 TAILQ_INSERT_TAIL(&symlist, sym, link); 795 } 796 } 797 pclose(fp); 798 } 799 if (symend == NULL) { 800 if (sym != NULL) 801 symend = sym->symaddr; 802 else 803 symend = (char *)-1; 804 } 805 symcache = TAILQ_FIRST(&symlist); 806 } 807 808 static 809 const char * 810 address_to_symbol(void *kptr, struct save_ctx *ctx) 811 { 812 char *buf = ctx->save_buf; 813 int size = sizeof(ctx->save_buf); 814 815 if (symcache == NULL || 816 (char *)kptr < symbegin || (char *)kptr >= symend 817 ) { 818 snprintf(buf, size, "%p", kptr); 819 return(buf); 820 } 821 while ((char *)symcache->symaddr < (char *)kptr) { 822 if (TAILQ_NEXT(symcache, link) == NULL) 823 break; 824 symcache = TAILQ_NEXT(symcache, link); 825 } 826 while ((char *)symcache->symaddr > (char *)kptr) { 827 if (symcache != TAILQ_FIRST(&symlist)) 828 symcache = TAILQ_PREV(symcache, symlist, link); 829 } 830 snprintf(buf, size, "%s+%d", symcache->symname, 831 (int)((char *)kptr - symcache->symaddr)); 832 return(buf); 833 } 834 835 static 836 struct ktr_buffer * 837 ktr_bufs_init(void) 838 { 839 struct ktr_buffer *ktr_bufs, *it; 840 int i; 841 842 ktr_bufs = malloc(sizeof(*ktr_bufs) * ncpus); 843 if (!ktr_bufs) 844 err(1, "can't allocate data structures"); 845 for (i = 0; i < ncpus; ++i) { 846 it = ktr_bufs + i; 847 it->ents = malloc(sizeof(struct ktr_entry) * entries_per_buf); 848 if (it->ents == NULL) 849 err(1, "can't allocate data structures"); 850 it->reset = 1; 851 it->beg_idx = -1; 852 it->end_idx = -1; 853 } 854 return ktr_bufs; 855 } 856 857 static 858 void 859 get_indices(struct ktr_entry **ktr_kbuf, int *ktr_idx) 860 { 861 static struct ktr_cpu *ktr_cpus; 862 int i; 863 864 if (ktr_cpus == NULL) 865 ktr_cpus = malloc(sizeof(*ktr_cpus) * ncpus); 866 867 if (ktr_version < KTR_VERSION_KTR_CPU) { 868 if (kvm_read(kd, nl_version_ktr_idx[0].n_value, ktr_idx, 869 sizeof(*ktr_idx) * ncpus) == -1) { 870 errx(1, "%s", kvm_geterr(kd)); 871 } 872 if (ktr_kbuf[0] == NULL) { 873 if (kvm_read(kd, nl_version_ktr_idx[1].n_value, 874 ktr_kbuf, sizeof(*ktr_kbuf) * ncpus) == -1) { 875 errx(1, "%s", kvm_geterr(kd)); 876 } 877 } 878 } else { 879 if (kvm_read(kd, nl_version_ktr_cpu[0].n_value, 880 ktr_cpus, sizeof(*ktr_cpus) * ncpus) == -1) { 881 errx(1, "%s", kvm_geterr(kd)); 882 } 883 for (i = 0; i < ncpus; ++i) { 884 ktr_idx[i] = ktr_cpus[i].core.ktr_idx; 885 ktr_kbuf[i] = ktr_cpus[i].core.ktr_buf; 886 } 887 } 888 } 889 890 /* 891 * Get the trace buffer data from the kernel 892 */ 893 static 894 void 895 load_bufs(struct ktr_buffer *ktr_bufs, struct ktr_entry **kbufs, int *ktr_idx) 896 { 897 struct ktr_buffer *kbuf; 898 int i; 899 900 get_indices(kbufs, ktr_idx); 901 for (i = 0; i < ncpus; ++i) { 902 kbuf = &ktr_bufs[i]; 903 if (ktr_idx[i] == kbuf->end_idx) 904 continue; 905 kbuf->end_idx = ktr_idx[i]; 906 907 /* 908 * If we do not have a notion of the beginning index, assume 909 * it is entries_per_buf before the ending index. Don't 910 * worry about underflows/negative numbers, the indices will 911 * be masked. 912 */ 913 if (kbuf->reset) { 914 kbuf->beg_idx = kbuf->end_idx - entries_per_buf + 1; 915 kbuf->reset = 0; 916 } 917 if (kvm_read(kd, (uintptr_t)kbufs[i], ktr_bufs[i].ents, 918 sizeof(struct ktr_entry) * entries_per_buf) 919 == -1) 920 errx(1, "%s", kvm_geterr(kd)); 921 kbuf->modified = 1; 922 kbuf->beg_idx = earliest_ts(kbuf); 923 } 924 925 } 926 927 /* 928 * Locate the earliest timestamp iterating backwards from end_idx, but 929 * not going further back then beg_idx. We have to do this because 930 * the kernel uses a circulating buffer. 931 */ 932 static 933 int 934 earliest_ts(struct ktr_buffer *buf) 935 { 936 struct ktr_entry *save; 937 int count, scan, i, earliest; 938 939 count = 0; 940 earliest = buf->end_idx - 1; 941 save = &buf->ents[earliest & fifo_mask]; 942 for (scan = buf->end_idx - 1; scan != buf->beg_idx -1; --scan) { 943 i = scan & fifo_mask; 944 if (buf->ents[i].ktr_timestamp <= save->ktr_timestamp && 945 buf->ents[i].ktr_timestamp > 0) 946 earliest = scan; 947 /* 948 * We may have gotten so far behind that beg_idx wrapped 949 * more then once around the buffer. Just stop 950 */ 951 if (++count == entries_per_buf) 952 break; 953 } 954 return earliest; 955 } 956 957 static 958 void 959 iterate_buf(FILE *fo, struct ktr_buffer *ktr_bufs, int cpu, 960 u_int64_t *last_timestamp, ktr_iter_cb_t cb) 961 { 962 struct ktr_buffer *buf = ktr_bufs + cpu; 963 964 if (buf->modified == 0) 965 return; 966 if (*last_timestamp == 0) { 967 *last_timestamp = 968 buf->ents[buf->beg_idx & fifo_mask].ktr_timestamp; 969 } 970 while (buf->beg_idx != buf->end_idx) { 971 cb(fo, cpu, buf->beg_idx, 972 &buf->ents[buf->beg_idx & fifo_mask], 973 last_timestamp); 974 ++buf->beg_idx; 975 } 976 buf->modified = 0; 977 } 978 979 static 980 void 981 iterate_bufs_timesorted(FILE *fo, struct ktr_buffer *ktr_bufs, 982 u_int64_t *last_timestamp, ktr_iter_cb_t cb) 983 { 984 struct ktr_entry *ent; 985 struct ktr_buffer *buf; 986 int n, bestn; 987 u_int64_t ts; 988 static int row = 0; 989 990 for (;;) { 991 ts = 0; 992 bestn = -1; 993 for (n = 0; n < ncpus; ++n) { 994 buf = ktr_bufs + n; 995 if (buf->beg_idx == buf->end_idx) 996 continue; 997 ent = &buf->ents[buf->beg_idx & fifo_mask]; 998 if (ts == 0 || (ts >= ent->ktr_timestamp)) { 999 ts = ent->ktr_timestamp; 1000 bestn = n; 1001 } 1002 } 1003 if ((bestn < 0) || (ts < *last_timestamp)) 1004 break; 1005 buf = ktr_bufs + bestn; 1006 cb(fo, bestn, row, 1007 &buf->ents[buf->beg_idx & fifo_mask], 1008 last_timestamp); 1009 ++buf->beg_idx; 1010 *last_timestamp = ts; 1011 ++row; 1012 } 1013 } 1014 1015 static 1016 void 1017 kvmfprintf(FILE *fp, const char *ctl, va_list va) 1018 { 1019 int n; 1020 int is_long; 1021 int is_done; 1022 char fmt[256]; 1023 static struct save_ctx strctx; 1024 const char *s; 1025 1026 while (*ctl) { 1027 for (n = 0; ctl[n]; ++n) { 1028 fmt[n] = ctl[n]; 1029 if (ctl[n] == '%') 1030 break; 1031 } 1032 if (n == 0) { 1033 is_long = 0; 1034 is_done = 0; 1035 n = 1; 1036 while (n < (int)sizeof(fmt)) { 1037 fmt[n] = ctl[n]; 1038 fmt[n+1] = 0; 1039 1040 switch(ctl[n]) { 1041 case 'p': 1042 is_long = 1; 1043 /* fall through */ 1044 case 'd': 1045 case 'i': 1046 case 'u': 1047 case 'x': 1048 case 'o': 1049 case 'X': 1050 /* 1051 * Integral 1052 */ 1053 switch(is_long) { 1054 case 0: 1055 fprintf(fp, fmt, 1056 va_arg(va, int)); 1057 break; 1058 case 1: 1059 fprintf(fp, fmt, 1060 va_arg(va, long)); 1061 break; 1062 case 2: 1063 fprintf(fp, fmt, 1064 va_arg(va, long long)); 1065 break; 1066 case 3: 1067 fprintf(fp, fmt, 1068 va_arg(va, size_t)); 1069 break; 1070 } 1071 ++n; 1072 is_done = 1; 1073 break; 1074 case 'c': 1075 fprintf(fp, "%c", va_arg(va, int)); 1076 ++n; 1077 is_done = 1; 1078 break; 1079 case 's': 1080 /* 1081 * String 1082 */ 1083 s = kvm_string(va_arg(va, char *), &strctx); 1084 fwrite(s, 1, strlen(s), fp); 1085 ++n; 1086 is_done = 1; 1087 break; 1088 case 'f': 1089 /* 1090 * Floating 1091 */ 1092 fprintf(fp, fmt, 1093 va_arg(va, double)); 1094 ++n; 1095 break; 1096 case 'j': 1097 case 't': 1098 is_long = 2; 1099 break; 1100 case 'z': 1101 is_long = 3; 1102 break; 1103 case 'h': 1104 is_long = 0; 1105 break; 1106 case 'l': 1107 if (is_long) 1108 is_long = 2; 1109 else 1110 is_long = 1; 1111 break; 1112 case '#': 1113 case '.': 1114 case '-': 1115 case '+': 1116 case '0': 1117 case '1': 1118 case '2': 1119 case '3': 1120 case '4': 1121 case '5': 1122 case '6': 1123 case '7': 1124 case '8': 1125 case '9': 1126 break; 1127 default: 1128 is_done = 1; 1129 break; 1130 } 1131 if (is_done) 1132 break; 1133 ++n; 1134 } 1135 } else { 1136 fmt[n] = 0; 1137 fprintf(fp, fmt, NULL); 1138 } 1139 ctl += n; 1140 } 1141 } 1142 1143 static void 1144 usage(void) 1145 { 1146 fprintf(stderr, "usage: ktrdump [-acfilnpqrstx] [-A factor] " 1147 "[-N execfile] [-M corefile] [-o outfile]\n"); 1148 exit(1); 1149 } 1150 1151 enum argument_class { 1152 ARGCLASS_NONE, 1153 ARGCLASS_INTEGER, 1154 ARGCLASS_FP, 1155 ARGCLASS_MEMORY, 1156 ARGCLASS_ERR, 1157 }; 1158 static size_t 1159 conversion_size(const char *fmt, enum argument_class *argclass) 1160 { 1161 const char *p; 1162 size_t convsize, intsz; 1163 1164 *argclass = ARGCLASS_ERR; 1165 if (fmt[0] != '%') 1166 return -1; 1167 1168 convsize = -1; 1169 for (p = fmt + 1; p[0]; ++p) { 1170 int again = 0; 1171 /* 1172 * Eat flags. Notice this will accept duplicate 1173 * flags. 1174 */ 1175 switch (p[0]) { 1176 case '#': 1177 case '0': 1178 case '-': 1179 case ' ': 1180 case '+': 1181 case '\'': 1182 again = !0; 1183 break; 1184 } 1185 if (!again) 1186 break; 1187 } 1188 /* Eat minimum field width, if any */ 1189 for (; isdigit(p[0]); ++p) 1190 ; 1191 if (p[0] == '.') 1192 ++p; 1193 /* Eat precision, if any */ 1194 for (; isdigit(p[0]); ++p) 1195 ; 1196 intsz = 0; 1197 switch (p[0]) { 1198 case 'h': 1199 if (p[1] == 'h') { 1200 ++p; 1201 intsz = sizeof(char); 1202 } else { 1203 intsz = sizeof(short); 1204 } 1205 break; 1206 case 'l': 1207 if (p[1] == 'l') { 1208 ++p; 1209 intsz = sizeof(long long); 1210 } else { 1211 intsz = sizeof(long); 1212 } 1213 break; 1214 case 'j': 1215 intsz = sizeof(intmax_t); 1216 break; 1217 case 't': 1218 intsz = sizeof(ptrdiff_t); 1219 break; 1220 case 'z': 1221 intsz = sizeof(size_t); 1222 break; 1223 default: 1224 p--; /* Anticipate the ++p that follows. Yes, I know. Eeek. */ 1225 break; 1226 } 1227 if (intsz == 0) 1228 intsz = sizeof(int); 1229 ++p; 1230 1231 switch (p[0]) { 1232 case 'c': 1233 /* for %c, we only store 1 byte in the ktr entry */ 1234 convsize = sizeof(char); 1235 *argclass = ARGCLASS_INTEGER; 1236 break; 1237 case 'd': 1238 case 'i': 1239 case 'o': 1240 case 'u': 1241 case 'x': 1242 case 'X': 1243 convsize = intsz; 1244 *argclass = ARGCLASS_INTEGER; 1245 break; 1246 case 'p': 1247 convsize = sizeof(void *); 1248 *argclass = ARGCLASS_INTEGER; 1249 break; 1250 case 'f': 1251 if (p[-1] == 'l') 1252 convsize = sizeof(double); 1253 else 1254 convsize = sizeof(float); 1255 *argclass = ARGCLASS_FP; 1256 break; 1257 case 's': 1258 convsize = sizeof(char *); 1259 *argclass = ARGCLASS_INTEGER; 1260 break; 1261 case '%': 1262 convsize = 0; 1263 *argclass = ARGCLASS_NONE; 1264 break; 1265 default: 1266 fprintf(stderr, "Unknown conversion specifier %c " 1267 "in fmt starting with %s\n", p[0], fmt - 1); 1268 return -2; 1269 } 1270 return convsize; 1271 } 1272 1273 #ifdef __x86_64__ 1274 static int 1275 va_list_push_integral(struct my_va_list *valist, void *val, size_t valsize, 1276 size_t *stacksize) 1277 { 1278 uint64_t r; 1279 1280 switch (valsize) { 1281 case 1: 1282 r = *(uint8_t *)val; break; 1283 case 2: 1284 r = *(uint32_t *)val; break; 1285 case 4: 1286 r = (*(uint32_t *)val); break; 1287 case 8: 1288 r = *(uint64_t *)val; break; 1289 default: 1290 err(1, "WTF"); 1291 } 1292 /* we always need to push the full 8 bytes */ 1293 if ((valist->gp_offset + valsize) <= 48) { /* got a free reg */ 1294 1295 memcpy(((char *)valist->reg_save_area + valist->gp_offset), 1296 &r, sizeof(r)); 1297 valist->gp_offset += sizeof(r); 1298 return 0; 1299 } 1300 /* push to "stack" */ 1301 if (!(valist->overflow_arg_area = realloc(valist->overflow_arg_area, 1302 *stacksize + sizeof(r)))) 1303 return -1; 1304 /* 1305 * Keep a pointer to the start of the allocated memory block so 1306 * we can free it later. We need to update it after every realloc(). 1307 */ 1308 valist->overflow_arg_area_save = valist->overflow_arg_area; 1309 memcpy((char *)valist->overflow_arg_area + *stacksize, &r, sizeof(r)); 1310 *stacksize += sizeof(r); 1311 return 0; 1312 } 1313 1314 static void 1315 va_list_rewind(struct my_va_list *valist) 1316 { 1317 valist->gp_offset = 0; 1318 } 1319 1320 static void 1321 va_list_cleanup(machine_va_list *_valist) 1322 { 1323 machine_va_list valist; 1324 if (!_valist || !*_valist) 1325 return; 1326 valist = *_valist; 1327 if (valist->reg_save_area) 1328 free(valist->reg_save_area); 1329 if (valist->overflow_arg_area_save) 1330 free(valist->overflow_arg_area_save); 1331 free(valist); 1332 } 1333 1334 static int 1335 va_list_from_blob(machine_va_list *_valist, const char *fmt, char *blob, size_t blobsize) 1336 { 1337 machine_va_list valist; 1338 struct reg_save_area *regs; 1339 enum argument_class argclass; 1340 const char *f; 1341 size_t stacksize, sz; 1342 1343 if (!(valist = malloc(sizeof(*valist)))) 1344 return -1; 1345 if (!(regs = malloc(sizeof(*regs)))) 1346 goto free_valist; 1347 *valist = (struct my_va_list) { 1348 .gp_offset = 0, 1349 .fp_offset = 0, 1350 .overflow_arg_area = NULL, 1351 .reg_save_area = regs, 1352 .overflow_arg_area_save = NULL, 1353 }; 1354 stacksize = 0; 1355 1356 for (f = fmt; *f != '\0'; ++f) { 1357 if (*f != '%') 1358 continue; 1359 sz = conversion_size(f, &argclass); 1360 if (argclass == ARGCLASS_INTEGER) { 1361 if (blobsize < sz) { 1362 fprintf(stderr, "not enough data available " 1363 "for format: %s\n", fmt); 1364 goto free_areas; 1365 } 1366 if (va_list_push_integral(valist, blob, sz, &stacksize)) 1367 goto free_areas; 1368 blob += sz; 1369 blobsize -= sz; 1370 } else if (argclass != ARGCLASS_NONE) 1371 goto free_areas; 1372 /* walk past the '%' */ 1373 ++f; 1374 } 1375 if (blobsize) { 1376 fprintf(stderr, "Couldn't consume all data for format %s " 1377 "(%zu bytes left over)\n", fmt, blobsize); 1378 goto free_areas; 1379 } 1380 va_list_rewind(valist); 1381 *_valist = valist; 1382 return 0; 1383 free_areas: 1384 if (valist->reg_save_area) 1385 free(valist->reg_save_area); 1386 if (valist->overflow_arg_area_save) 1387 free(valist->overflow_arg_area_save); 1388 free_valist: 1389 free(valist); 1390 *_valist = NULL; 1391 return -1; 1392 } 1393 1394 #else 1395 #error "Don't know how to get a va_list on this platform" 1396 #endif 1397