1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <strings.h> 31 #include <errno.h> 32 #include <unistd.h> 33 #include <limits.h> 34 #include <assert.h> 35 #include <ctype.h> 36 #include <alloca.h> 37 #include <dt_impl.h> 38 39 /* 40 * We declare this here because (1) we need it and (2) we want to avoid a 41 * dependency on libm in libdtrace. 42 */ 43 static long double 44 dt_fabsl(long double x) 45 { 46 if (x < 0) 47 return (-x); 48 49 return (x); 50 } 51 52 static int 53 dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last, 54 dtrace_bufdesc_t *buf, size_t offs) 55 { 56 dtrace_probedesc_t *pd = data->dtpda_pdesc, *npd; 57 dtrace_eprobedesc_t *epd = data->dtpda_edesc, *nepd; 58 char *p = pd->dtpd_provider, *n = pd->dtpd_name, *sub; 59 dtrace_flowkind_t flow = DTRACEFLOW_NONE; 60 const char *str = NULL; 61 static const char *e_str[2] = { " -> ", " => " }; 62 static const char *r_str[2] = { " <- ", " <= " }; 63 static const char *ent = "entry", *ret = "return"; 64 static int entlen = 0, retlen = 0; 65 dtrace_epid_t next, id = epd->dtepd_epid; 66 int rval; 67 68 if (entlen == 0) { 69 assert(retlen == 0); 70 entlen = strlen(ent); 71 retlen = strlen(ret); 72 } 73 74 /* 75 * If the name of the probe is "entry" or ends with "-entry", we 76 * treat it as an entry; if it is "return" or ends with "-return", 77 * we treat it as a return. (This allows application-provided probes 78 * like "method-entry" or "function-entry" to participate in flow 79 * indentation -- without accidentally misinterpreting popular probe 80 * names like "carpentry", "gentry" or "Coventry".) 81 */ 82 if ((sub = strstr(n, ent)) != NULL && sub[entlen] == '\0' && 83 (sub == n || sub[-1] == '-')) { 84 flow = DTRACEFLOW_ENTRY; 85 str = e_str[strcmp(p, "syscall") == 0]; 86 } else if ((sub = strstr(n, ret)) != NULL && sub[retlen] == '\0' && 87 (sub == n || sub[-1] == '-')) { 88 flow = DTRACEFLOW_RETURN; 89 str = r_str[strcmp(p, "syscall") == 0]; 90 } 91 92 /* 93 * If we're going to indent this, we need to check the ID of our last 94 * call. If we're looking at the same probe ID but a different EPID, 95 * we _don't_ want to indent. (Yes, there are some minor holes in 96 * this scheme -- it's a heuristic.) 97 */ 98 if (flow == DTRACEFLOW_ENTRY) { 99 if ((last != DTRACE_EPIDNONE && id != last && 100 pd->dtpd_id == dtp->dt_pdesc[last]->dtpd_id)) 101 flow = DTRACEFLOW_NONE; 102 } 103 104 /* 105 * If we're going to unindent this, it's more difficult to see if 106 * we don't actually want to unindent it -- we need to look at the 107 * _next_ EPID. 108 */ 109 if (flow == DTRACEFLOW_RETURN) { 110 offs += epd->dtepd_size; 111 112 do { 113 if (offs >= buf->dtbd_size) { 114 /* 115 * We're at the end -- maybe. If the oldest 116 * record is non-zero, we need to wrap. 117 */ 118 if (buf->dtbd_oldest != 0) { 119 offs = 0; 120 } else { 121 goto out; 122 } 123 } 124 125 next = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs); 126 127 if (next == DTRACE_EPIDNONE) 128 offs += sizeof (id); 129 } while (next == DTRACE_EPIDNONE); 130 131 if ((rval = dt_epid_lookup(dtp, next, &nepd, &npd)) != 0) 132 return (rval); 133 134 if (next != id && npd->dtpd_id == pd->dtpd_id) 135 flow = DTRACEFLOW_NONE; 136 } 137 138 out: 139 if (flow == DTRACEFLOW_ENTRY || flow == DTRACEFLOW_RETURN) { 140 data->dtpda_prefix = str; 141 } else { 142 data->dtpda_prefix = "| "; 143 } 144 145 if (flow == DTRACEFLOW_RETURN && data->dtpda_indent > 0) 146 data->dtpda_indent -= 2; 147 148 data->dtpda_flow = flow; 149 150 return (0); 151 } 152 153 static int 154 dt_nullprobe() 155 { 156 return (DTRACE_CONSUME_THIS); 157 } 158 159 static int 160 dt_nullrec() 161 { 162 return (DTRACE_CONSUME_NEXT); 163 } 164 165 int 166 dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val, 167 uint64_t normal, long double total, char positives, char negatives) 168 { 169 long double f; 170 uint_t depth, len = 40; 171 172 const char *ats = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; 173 const char *spaces = " "; 174 175 assert(strlen(ats) == len && strlen(spaces) == len); 176 assert(!(total == 0 && (positives || negatives))); 177 assert(!(val < 0 && !negatives)); 178 assert(!(val > 0 && !positives)); 179 assert(!(val != 0 && total == 0)); 180 181 if (!negatives) { 182 if (positives) { 183 f = (dt_fabsl((long double)val) * len) / total; 184 depth = (uint_t)(f + 0.5); 185 } else { 186 depth = 0; 187 } 188 189 return (dt_printf(dtp, fp, "|%s%s %-9lld\n", ats + len - depth, 190 spaces + depth, (long long)val / normal)); 191 } 192 193 if (!positives) { 194 f = (dt_fabsl((long double)val) * len) / total; 195 depth = (uint_t)(f + 0.5); 196 197 return (dt_printf(dtp, fp, "%s%s| %-9lld\n", spaces + depth, 198 ats + len - depth, (long long)val / normal)); 199 } 200 201 /* 202 * If we're here, we have both positive and negative bucket values. 203 * To express this graphically, we're going to generate both positive 204 * and negative bars separated by a centerline. These bars are half 205 * the size of normal quantize()/lquantize() bars, so we divide the 206 * length in half before calculating the bar length. 207 */ 208 len /= 2; 209 ats = &ats[len]; 210 spaces = &spaces[len]; 211 212 f = (dt_fabsl((long double)val) * len) / total; 213 depth = (uint_t)(f + 0.5); 214 215 if (val <= 0) { 216 return (dt_printf(dtp, fp, "%s%s|%*s %-9lld\n", spaces + depth, 217 ats + len - depth, len, "", (long long)val / normal)); 218 } else { 219 return (dt_printf(dtp, fp, "%20s|%s%s %-9lld\n", "", 220 ats + len - depth, spaces + depth, 221 (long long)val / normal)); 222 } 223 } 224 225 int 226 dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, 227 size_t size, uint64_t normal) 228 { 229 const int64_t *data = addr; 230 int i, first_bin = 0, last_bin = DTRACE_QUANTIZE_NBUCKETS - 1; 231 long double total = 0; 232 char positives = 0, negatives = 0; 233 234 if (size != DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t)) 235 return (dt_set_errno(dtp, EDT_DMISMATCH)); 236 237 while (first_bin < DTRACE_QUANTIZE_NBUCKETS - 1 && data[first_bin] == 0) 238 first_bin++; 239 240 if (first_bin == DTRACE_QUANTIZE_NBUCKETS - 1) { 241 /* 242 * There isn't any data. This is possible if (and only if) 243 * negative increment values have been used. In this case, 244 * we'll print the buckets around 0. 245 */ 246 first_bin = DTRACE_QUANTIZE_ZEROBUCKET - 1; 247 last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 1; 248 } else { 249 if (first_bin > 0) 250 first_bin--; 251 252 while (last_bin > 0 && data[last_bin] == 0) 253 last_bin--; 254 255 if (last_bin < DTRACE_QUANTIZE_NBUCKETS - 1) 256 last_bin++; 257 } 258 259 for (i = first_bin; i <= last_bin; i++) { 260 positives |= (data[i] > 0); 261 negatives |= (data[i] < 0); 262 total += dt_fabsl((long double)data[i]); 263 } 264 265 if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value", 266 "------------- Distribution -------------", "count") < 0) 267 return (-1); 268 269 for (i = first_bin; i <= last_bin; i++) { 270 if (dt_printf(dtp, fp, "%16lld ", 271 (long long)DTRACE_QUANTIZE_BUCKETVAL(i)) < 0) 272 return (-1); 273 274 if (dt_print_quantline(dtp, fp, data[i], normal, total, 275 positives, negatives) < 0) 276 return (-1); 277 } 278 279 return (0); 280 } 281 282 int 283 dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, 284 size_t size, uint64_t normal) 285 { 286 const int64_t *data = addr; 287 int i, first_bin, last_bin, base; 288 uint64_t arg; 289 long double total = 0; 290 uint16_t step, levels; 291 char positives = 0, negatives = 0; 292 293 if (size < sizeof (uint64_t)) 294 return (dt_set_errno(dtp, EDT_DMISMATCH)); 295 296 arg = *data++; 297 size -= sizeof (uint64_t); 298 299 base = DTRACE_LQUANTIZE_BASE(arg); 300 step = DTRACE_LQUANTIZE_STEP(arg); 301 levels = DTRACE_LQUANTIZE_LEVELS(arg); 302 303 first_bin = 0; 304 last_bin = levels + 1; 305 306 if (size != sizeof (uint64_t) * (levels + 2)) 307 return (dt_set_errno(dtp, EDT_DMISMATCH)); 308 309 while (first_bin <= levels + 1 && data[first_bin] == 0) 310 first_bin++; 311 312 if (first_bin > levels + 1) { 313 first_bin = 0; 314 last_bin = 2; 315 } else { 316 if (first_bin > 0) 317 first_bin--; 318 319 while (last_bin > 0 && data[last_bin] == 0) 320 last_bin--; 321 322 if (last_bin < levels + 1) 323 last_bin++; 324 } 325 326 for (i = first_bin; i <= last_bin; i++) { 327 positives |= (data[i] > 0); 328 negatives |= (data[i] < 0); 329 total += dt_fabsl((long double)data[i]); 330 } 331 332 if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value", 333 "------------- Distribution -------------", "count") < 0) 334 return (-1); 335 336 for (i = first_bin; i <= last_bin; i++) { 337 char c[32]; 338 int err; 339 340 if (i == 0) { 341 (void) snprintf(c, sizeof (c), "< %d", 342 base / (uint32_t)normal); 343 err = dt_printf(dtp, fp, "%16s ", c); 344 } else if (i == levels + 1) { 345 (void) snprintf(c, sizeof (c), ">= %d", 346 base + (levels * step)); 347 err = dt_printf(dtp, fp, "%16s ", c); 348 } else { 349 err = dt_printf(dtp, fp, "%16d ", 350 base + (i - 1) * step); 351 } 352 353 if (err < 0 || dt_print_quantline(dtp, fp, data[i], normal, 354 total, positives, negatives) < 0) 355 return (-1); 356 } 357 358 return (0); 359 } 360 361 /*ARGSUSED*/ 362 static int 363 dt_print_average(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, 364 size_t size, uint64_t normal) 365 { 366 /* LINTED - alignment */ 367 uint64_t *data = (uint64_t *)addr; 368 369 return (dt_printf(dtp, fp, " %16lld", data[0] ? 370 (long long)(data[1] / normal / data[0]) : 0)); 371 } 372 373 /*ARGSUSED*/ 374 int 375 dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, 376 size_t nbytes, int width, int quiet) 377 { 378 /* 379 * If the byte stream is a series of printable characters, followed by 380 * a terminating byte, we print it out as a string. Otherwise, we 381 * assume that it's something else and just print the bytes. 382 */ 383 int i, j, margin = 5; 384 char *c = (char *)addr; 385 386 if (nbytes == 0) 387 return (0); 388 389 if (dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET) 390 goto raw; 391 392 for (i = 0; i < nbytes; i++) { 393 /* 394 * We define a "printable character" to be one for which 395 * isprint(3C) returns non-zero, isspace(3C) returns non-zero, 396 * or a character which is either backspace or the bell. 397 * Backspace and the bell are regrettably special because 398 * they fail the first two tests -- and yet they are entirely 399 * printable. These are the only two control characters that 400 * have meaning for the terminal and for which isprint(3C) and 401 * isspace(3C) return 0. 402 */ 403 if (isprint(c[i]) || isspace(c[i]) || 404 c[i] == '\b' || c[i] == '\a') 405 continue; 406 407 if (c[i] == '\0' && i > 0) { 408 /* 409 * This looks like it might be a string. Before we 410 * assume that it is indeed a string, check the 411 * remainder of the byte range; if it contains 412 * additional non-nul characters, we'll assume that 413 * it's a binary stream that just happens to look like 414 * a string, and we'll print out the individual bytes. 415 */ 416 for (j = i + 1; j < nbytes; j++) { 417 if (c[j] != '\0') 418 break; 419 } 420 421 if (j != nbytes) 422 break; 423 424 if (quiet) 425 return (dt_printf(dtp, fp, "%s", c)); 426 else 427 return (dt_printf(dtp, fp, " %-*s", width, c)); 428 } 429 430 break; 431 } 432 433 if (i == nbytes) { 434 /* 435 * The byte range is all printable characters, but there is 436 * no trailing nul byte. We'll assume that it's a string and 437 * print it as such. 438 */ 439 char *s = alloca(nbytes + 1); 440 bcopy(c, s, nbytes); 441 s[nbytes] = '\0'; 442 return (dt_printf(dtp, fp, " %-*s", width, s)); 443 } 444 445 raw: 446 if (dt_printf(dtp, fp, "\n%*s ", margin, "") < 0) 447 return (-1); 448 449 for (i = 0; i < 16; i++) 450 if (dt_printf(dtp, fp, " %c", "0123456789abcdef"[i]) < 0) 451 return (-1); 452 453 if (dt_printf(dtp, fp, " 0123456789abcdef\n") < 0) 454 return (-1); 455 456 457 for (i = 0; i < nbytes; i += 16) { 458 if (dt_printf(dtp, fp, "%*s%5x:", margin, "", i) < 0) 459 return (-1); 460 461 for (j = i; j < i + 16 && j < nbytes; j++) { 462 if (dt_printf(dtp, fp, " %02x", (uchar_t)c[j]) < 0) 463 return (-1); 464 } 465 466 while (j++ % 16) { 467 if (dt_printf(dtp, fp, " ") < 0) 468 return (-1); 469 } 470 471 if (dt_printf(dtp, fp, " ") < 0) 472 return (-1); 473 474 for (j = i; j < i + 16 && j < nbytes; j++) { 475 if (dt_printf(dtp, fp, "%c", 476 c[j] < ' ' || c[j] > '~' ? '.' : c[j]) < 0) 477 return (-1); 478 } 479 480 if (dt_printf(dtp, fp, "\n") < 0) 481 return (-1); 482 } 483 484 return (0); 485 } 486 487 int 488 dt_print_stack(dtrace_hdl_t *dtp, FILE *fp, const char *format, 489 caddr_t addr, int depth, int size) 490 { 491 dtrace_syminfo_t dts; 492 GElf_Sym sym; 493 int i, indent; 494 char c[PATH_MAX * 2]; 495 uint64_t pc; 496 497 if (dt_printf(dtp, fp, "\n") < 0) 498 return (-1); 499 500 if (format == NULL) 501 format = "%s"; 502 503 if (dtp->dt_options[DTRACEOPT_STACKINDENT] != DTRACEOPT_UNSET) 504 indent = (int)dtp->dt_options[DTRACEOPT_STACKINDENT]; 505 else 506 indent = _dtrace_stkindent; 507 508 for (i = 0; i < depth; i++) { 509 switch (size) { 510 case sizeof (uint32_t): 511 /* LINTED - alignment */ 512 pc = *((uint32_t *)addr); 513 break; 514 515 case sizeof (uint64_t): 516 /* LINTED - alignment */ 517 pc = *((uint64_t *)addr); 518 break; 519 520 default: 521 return (dt_set_errno(dtp, EDT_BADSTACKPC)); 522 } 523 524 if (pc == NULL) 525 break; 526 527 addr += size; 528 529 if (dt_printf(dtp, fp, "%*s", indent, "") < 0) 530 return (-1); 531 532 if (dtrace_lookup_by_addr(dtp, pc, &sym, &dts) == 0) { 533 if (pc > sym.st_value) { 534 (void) snprintf(c, sizeof (c), "%s`%s+0x%llx", 535 dts.dts_object, dts.dts_name, 536 pc - sym.st_value); 537 } else { 538 (void) snprintf(c, sizeof (c), "%s`%s", 539 dts.dts_object, dts.dts_name); 540 } 541 } else { 542 /* 543 * We'll repeat the lookup, but this time we'll specify 544 * a NULL GElf_Sym -- indicating that we're only 545 * interested in the containing module. 546 */ 547 if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) { 548 (void) snprintf(c, sizeof (c), "%s`0x%llx", 549 dts.dts_object, pc); 550 } else { 551 (void) snprintf(c, sizeof (c), "0x%llx", pc); 552 } 553 } 554 555 if (dt_printf(dtp, fp, format, c) < 0) 556 return (-1); 557 558 if (dt_printf(dtp, fp, "\n") < 0) 559 return (-1); 560 } 561 562 return (0); 563 } 564 565 int 566 dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, 567 caddr_t addr, uint64_t arg) 568 { 569 /* LINTED - alignment */ 570 uint64_t *pc = (uint64_t *)addr; 571 uint32_t depth = DTRACE_USTACK_NFRAMES(arg); 572 uint32_t strsize = DTRACE_USTACK_STRSIZE(arg); 573 const char *strbase = addr + (depth + 1) * sizeof (uint64_t); 574 const char *str = strsize ? strbase : NULL; 575 int err = 0; 576 577 char name[PATH_MAX], objname[PATH_MAX], c[PATH_MAX * 2]; 578 struct ps_prochandle *P; 579 GElf_Sym sym; 580 int i, indent; 581 pid_t pid; 582 583 if (depth == 0) 584 return (0); 585 586 pid = (pid_t)*pc++; 587 588 if (dt_printf(dtp, fp, "\n") < 0) 589 return (-1); 590 591 if (format == NULL) 592 format = "%s"; 593 594 if (dtp->dt_options[DTRACEOPT_STACKINDENT] != DTRACEOPT_UNSET) 595 indent = (int)dtp->dt_options[DTRACEOPT_STACKINDENT]; 596 else 597 indent = _dtrace_stkindent; 598 599 /* 600 * Ultimately, we need to add an entry point in the library vector for 601 * determining <symbol, offset> from <pid, address>. For now, if 602 * this is a vector open, we just print the raw address or string. 603 */ 604 if (dtp->dt_vector == NULL) 605 P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0); 606 else 607 P = NULL; 608 609 if (P != NULL) 610 dt_proc_lock(dtp, P); /* lock handle while we perform lookups */ 611 612 for (i = 0; i < depth && pc[i] != NULL; i++) { 613 const prmap_t *map; 614 615 if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0) 616 break; 617 618 if (P != NULL && Plookup_by_addr(P, pc[i], 619 name, sizeof (name), &sym) == 0) { 620 (void) Pobjname(P, pc[i], objname, sizeof (objname)); 621 622 if (pc[i] > sym.st_value) { 623 (void) snprintf(c, sizeof (c), 624 "%s`%s+0x%llx", dt_basename(objname), name, 625 (u_longlong_t)(pc[i] - sym.st_value)); 626 } else { 627 (void) snprintf(c, sizeof (c), 628 "%s`%s", dt_basename(objname), name); 629 } 630 } else if (str != NULL && str[0] != '\0' && str[0] != '@' && 631 (P != NULL && ((map = Paddr_to_map(P, pc[i])) == NULL || 632 (map->pr_mflags & MA_WRITE)))) { 633 /* 634 * If the current string pointer in the string table 635 * does not point to an empty string _and_ the program 636 * counter falls in a writable region, we'll use the 637 * string from the string table instead of the raw 638 * address. This last condition is necessary because 639 * some (broken) ustack helpers will return a string 640 * even for a program counter that they can't 641 * identify. If we have a string for a program 642 * counter that falls in a segment that isn't 643 * writable, we assume that we have fallen into this 644 * case and we refuse to use the string. 645 */ 646 (void) snprintf(c, sizeof (c), "%s", str); 647 } else { 648 if (P != NULL && Pobjname(P, pc[i], objname, 649 sizeof (objname)) != NULL) { 650 (void) snprintf(c, sizeof (c), "%s`0x%llx", 651 dt_basename(objname), (u_longlong_t)pc[i]); 652 } else { 653 (void) snprintf(c, sizeof (c), "0x%llx", 654 (u_longlong_t)pc[i]); 655 } 656 } 657 658 if ((err = dt_printf(dtp, fp, format, c)) < 0) 659 break; 660 661 if ((err = dt_printf(dtp, fp, "\n")) < 0) 662 break; 663 664 if (str != NULL && str[0] == '@') { 665 /* 666 * If the first character of the string is an "at" sign, 667 * then the string is inferred to be an annotation -- 668 * and it is printed out beneath the frame and offset 669 * with brackets. 670 */ 671 if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0) 672 break; 673 674 (void) snprintf(c, sizeof (c), " [ %s ]", &str[1]); 675 676 if ((err = dt_printf(dtp, fp, format, c)) < 0) 677 break; 678 679 if ((err = dt_printf(dtp, fp, "\n")) < 0) 680 break; 681 } 682 683 if (str != NULL) { 684 str += strlen(str) + 1; 685 if (str - strbase >= strsize) 686 str = NULL; 687 } 688 } 689 690 if (P != NULL) { 691 dt_proc_unlock(dtp, P); 692 dt_proc_release(dtp, P); 693 } 694 695 return (err); 696 } 697 698 static int 699 dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act) 700 { 701 /* LINTED - alignment */ 702 uint64_t pid = ((uint64_t *)addr)[0]; 703 /* LINTED - alignment */ 704 uint64_t pc = ((uint64_t *)addr)[1]; 705 const char *format = " %-50s"; 706 char *s; 707 int n, len = 256; 708 709 if (act == DTRACEACT_USYM && dtp->dt_vector == NULL) { 710 struct ps_prochandle *P; 711 712 if ((P = dt_proc_grab(dtp, pid, 713 PGRAB_RDONLY | PGRAB_FORCE, 0)) != NULL) { 714 GElf_Sym sym; 715 716 dt_proc_lock(dtp, P); 717 718 if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0) 719 pc = sym.st_value; 720 721 dt_proc_unlock(dtp, P); 722 dt_proc_release(dtp, P); 723 } 724 } 725 726 do { 727 n = len; 728 s = alloca(n); 729 } while ((len = dtrace_uaddr2str(dtp, pid, pc, s, n)) >= n); 730 731 return (dt_printf(dtp, fp, format, s)); 732 } 733 734 int 735 dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 736 { 737 /* LINTED - alignment */ 738 uint64_t pid = ((uint64_t *)addr)[0]; 739 /* LINTED - alignment */ 740 uint64_t pc = ((uint64_t *)addr)[1]; 741 int err = 0; 742 743 char objname[PATH_MAX], c[PATH_MAX * 2]; 744 struct ps_prochandle *P; 745 746 if (format == NULL) 747 format = " %-50s"; 748 749 /* 750 * See the comment in dt_print_ustack() for the rationale for 751 * printing raw addresses in the vectored case. 752 */ 753 if (dtp->dt_vector == NULL) 754 P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0); 755 else 756 P = NULL; 757 758 if (P != NULL) 759 dt_proc_lock(dtp, P); /* lock handle while we perform lookups */ 760 761 if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != NULL) { 762 (void) snprintf(c, sizeof (c), "%s", dt_basename(objname)); 763 } else { 764 (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); 765 } 766 767 err = dt_printf(dtp, fp, format, c); 768 769 if (P != NULL) { 770 dt_proc_unlock(dtp, P); 771 dt_proc_release(dtp, P); 772 } 773 774 return (err); 775 } 776 777 static int 778 dt_print_sym(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 779 { 780 /* LINTED - alignment */ 781 uint64_t pc = *((uint64_t *)addr); 782 dtrace_syminfo_t dts; 783 GElf_Sym sym; 784 char c[PATH_MAX * 2]; 785 786 if (format == NULL) 787 format = " %-50s"; 788 789 if (dtrace_lookup_by_addr(dtp, pc, &sym, &dts) == 0) { 790 (void) snprintf(c, sizeof (c), "%s`%s", 791 dts.dts_object, dts.dts_name); 792 } else { 793 /* 794 * We'll repeat the lookup, but this time we'll specify a 795 * NULL GElf_Sym -- indicating that we're only interested in 796 * the containing module. 797 */ 798 if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) { 799 (void) snprintf(c, sizeof (c), "%s`0x%llx", 800 dts.dts_object, (u_longlong_t)pc); 801 } else { 802 (void) snprintf(c, sizeof (c), "0x%llx", 803 (u_longlong_t)pc); 804 } 805 } 806 807 if (dt_printf(dtp, fp, format, c) < 0) 808 return (-1); 809 810 return (0); 811 } 812 813 int 814 dt_print_mod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 815 { 816 /* LINTED - alignment */ 817 uint64_t pc = *((uint64_t *)addr); 818 dtrace_syminfo_t dts; 819 char c[PATH_MAX * 2]; 820 821 if (format == NULL) 822 format = " %-50s"; 823 824 if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) { 825 (void) snprintf(c, sizeof (c), "%s", dts.dts_object); 826 } else { 827 (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); 828 } 829 830 if (dt_printf(dtp, fp, format, c) < 0) 831 return (-1); 832 833 return (0); 834 } 835 836 typedef struct dt_normal { 837 dtrace_aggvarid_t dtnd_id; 838 uint64_t dtnd_normal; 839 } dt_normal_t; 840 841 static int 842 dt_normalize_agg(const dtrace_aggdata_t *aggdata, void *arg) 843 { 844 dt_normal_t *normal = arg; 845 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 846 dtrace_aggvarid_t id = normal->dtnd_id; 847 uintptr_t data = (uintptr_t)aggdata->dtada_data; 848 849 if (agg->dtagd_nrecs == 0) 850 return (DTRACE_AGGWALK_NEXT); 851 852 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 853 return (DTRACE_AGGWALK_NEXT); 854 855 ((dtrace_aggdata_t *)aggdata)->dtada_normal = normal->dtnd_normal; 856 return (DTRACE_AGGWALK_NORMALIZE); 857 } 858 859 static int 860 dt_normalize(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec) 861 { 862 dt_normal_t normal; 863 caddr_t addr; 864 865 /* 866 * We (should) have two records: the aggregation ID followed by the 867 * normalization value. 868 */ 869 addr = base + rec->dtrd_offset; 870 871 if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) 872 return (dt_set_errno(dtp, EDT_BADNORMAL)); 873 874 /* LINTED - alignment */ 875 normal.dtnd_id = *((dtrace_aggvarid_t *)addr); 876 rec++; 877 878 if (rec->dtrd_action != DTRACEACT_LIBACT) 879 return (dt_set_errno(dtp, EDT_BADNORMAL)); 880 881 if (rec->dtrd_arg != DT_ACT_NORMALIZE) 882 return (dt_set_errno(dtp, EDT_BADNORMAL)); 883 884 addr = base + rec->dtrd_offset; 885 886 switch (rec->dtrd_size) { 887 case sizeof (uint64_t): 888 /* LINTED - alignment */ 889 normal.dtnd_normal = *((uint64_t *)addr); 890 break; 891 case sizeof (uint32_t): 892 /* LINTED - alignment */ 893 normal.dtnd_normal = *((uint32_t *)addr); 894 break; 895 case sizeof (uint16_t): 896 /* LINTED - alignment */ 897 normal.dtnd_normal = *((uint16_t *)addr); 898 break; 899 case sizeof (uint8_t): 900 normal.dtnd_normal = *((uint8_t *)addr); 901 break; 902 default: 903 return (dt_set_errno(dtp, EDT_BADNORMAL)); 904 } 905 906 (void) dtrace_aggregate_walk(dtp, dt_normalize_agg, &normal); 907 908 return (0); 909 } 910 911 static int 912 dt_denormalize_agg(const dtrace_aggdata_t *aggdata, void *arg) 913 { 914 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 915 dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); 916 uintptr_t data = (uintptr_t)aggdata->dtada_data; 917 918 if (agg->dtagd_nrecs == 0) 919 return (DTRACE_AGGWALK_NEXT); 920 921 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 922 return (DTRACE_AGGWALK_NEXT); 923 924 return (DTRACE_AGGWALK_DENORMALIZE); 925 } 926 927 static int 928 dt_clear_agg(const dtrace_aggdata_t *aggdata, void *arg) 929 { 930 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 931 dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); 932 uintptr_t data = (uintptr_t)aggdata->dtada_data; 933 934 if (agg->dtagd_nrecs == 0) 935 return (DTRACE_AGGWALK_NEXT); 936 937 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 938 return (DTRACE_AGGWALK_NEXT); 939 940 return (DTRACE_AGGWALK_CLEAR); 941 } 942 943 typedef struct dt_trunc { 944 dtrace_aggvarid_t dttd_id; 945 uint64_t dttd_remaining; 946 } dt_trunc_t; 947 948 static int 949 dt_trunc_agg(const dtrace_aggdata_t *aggdata, void *arg) 950 { 951 dt_trunc_t *trunc = arg; 952 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 953 dtrace_aggvarid_t id = trunc->dttd_id; 954 uintptr_t data = (uintptr_t)aggdata->dtada_data; 955 956 if (agg->dtagd_nrecs == 0) 957 return (DTRACE_AGGWALK_NEXT); 958 959 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 960 return (DTRACE_AGGWALK_NEXT); 961 962 if (trunc->dttd_remaining == 0) 963 return (DTRACE_AGGWALK_REMOVE); 964 965 trunc->dttd_remaining--; 966 return (DTRACE_AGGWALK_NEXT); 967 } 968 969 static int 970 dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec) 971 { 972 dt_trunc_t trunc; 973 caddr_t addr; 974 int64_t remaining; 975 int (*func)(dtrace_hdl_t *, dtrace_aggregate_f *, void *); 976 977 /* 978 * We (should) have two records: the aggregation ID followed by the 979 * number of aggregation entries after which the aggregation is to be 980 * truncated. 981 */ 982 addr = base + rec->dtrd_offset; 983 984 if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) 985 return (dt_set_errno(dtp, EDT_BADTRUNC)); 986 987 /* LINTED - alignment */ 988 trunc.dttd_id = *((dtrace_aggvarid_t *)addr); 989 rec++; 990 991 if (rec->dtrd_action != DTRACEACT_LIBACT) 992 return (dt_set_errno(dtp, EDT_BADTRUNC)); 993 994 if (rec->dtrd_arg != DT_ACT_TRUNC) 995 return (dt_set_errno(dtp, EDT_BADTRUNC)); 996 997 addr = base + rec->dtrd_offset; 998 999 switch (rec->dtrd_size) { 1000 case sizeof (uint64_t): 1001 /* LINTED - alignment */ 1002 remaining = *((int64_t *)addr); 1003 break; 1004 case sizeof (uint32_t): 1005 /* LINTED - alignment */ 1006 remaining = *((int32_t *)addr); 1007 break; 1008 case sizeof (uint16_t): 1009 /* LINTED - alignment */ 1010 remaining = *((int16_t *)addr); 1011 break; 1012 case sizeof (uint8_t): 1013 remaining = *((int8_t *)addr); 1014 break; 1015 default: 1016 return (dt_set_errno(dtp, EDT_BADNORMAL)); 1017 } 1018 1019 if (remaining < 0) { 1020 func = dtrace_aggregate_walk_valsorted; 1021 remaining = -remaining; 1022 } else { 1023 func = dtrace_aggregate_walk_valrevsorted; 1024 } 1025 1026 assert(remaining >= 0); 1027 trunc.dttd_remaining = remaining; 1028 1029 (void) func(dtp, dt_trunc_agg, &trunc); 1030 1031 return (0); 1032 } 1033 1034 int 1035 dt_print_agg(const dtrace_aggdata_t *aggdata, void *arg) 1036 { 1037 int i, err = 0; 1038 dt_print_aggdata_t *pd = arg; 1039 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 1040 FILE *fp = pd->dtpa_fp; 1041 dtrace_hdl_t *dtp = pd->dtpa_dtp; 1042 dtrace_aggvarid_t aggvarid = pd->dtpa_id; 1043 uintptr_t data = (uintptr_t)aggdata->dtada_data; 1044 1045 if (pd->dtpa_allunprint) { 1046 if (agg->dtagd_flags & DTRACE_AGD_PRINTED) 1047 return (0); 1048 } else { 1049 /* 1050 * If we're not printing all unprinted aggregations, then the 1051 * aggregation variable ID denotes a specific aggregation 1052 * variable that we should print -- skip any other aggregations 1053 * that we encounter. 1054 */ 1055 if (agg->dtagd_nrecs == 0) 1056 return (0); 1057 1058 if (aggvarid != *(dtrace_aggvarid_t *)(data + 1059 agg->dtagd_rec[0].dtrd_offset)) 1060 return (0); 1061 } 1062 1063 /* 1064 * Iterate over each record description, printing the traced data, 1065 * skipping the first datum (the tuple member created by the compiler). 1066 */ 1067 for (i = 1; err >= 0 && i < agg->dtagd_nrecs; i++) { 1068 dtrace_recdesc_t *rec = &agg->dtagd_rec[i]; 1069 dtrace_actkind_t act = rec->dtrd_action; 1070 caddr_t addr = aggdata->dtada_data + rec->dtrd_offset; 1071 size_t size = rec->dtrd_size; 1072 uint64_t normal; 1073 1074 normal = DTRACEACT_ISAGG(act) ? aggdata->dtada_normal : 1; 1075 1076 if (act == DTRACEACT_STACK) { 1077 err = dt_print_stack(dtp, fp, NULL, addr, 1078 rec->dtrd_arg, rec->dtrd_size / rec->dtrd_arg); 1079 goto nextrec; 1080 } 1081 1082 if (act == DTRACEACT_USTACK || act == DTRACEACT_JSTACK) { 1083 err = dt_print_ustack(dtp, fp, NULL, addr, 1084 rec->dtrd_arg); 1085 goto nextrec; 1086 } 1087 1088 if (act == DTRACEACT_USYM || act == DTRACEACT_UADDR) { 1089 err = dt_print_usym(dtp, fp, addr, act); 1090 goto nextrec; 1091 } 1092 1093 if (act == DTRACEACT_UMOD) { 1094 err = dt_print_umod(dtp, fp, NULL, addr); 1095 goto nextrec; 1096 } 1097 1098 if (act == DTRACEACT_SYM) { 1099 err = dt_print_sym(dtp, fp, NULL, addr); 1100 goto nextrec; 1101 } 1102 1103 if (act == DTRACEACT_MOD) { 1104 err = dt_print_mod(dtp, fp, NULL, addr); 1105 goto nextrec; 1106 } 1107 1108 if (act == DTRACEAGG_QUANTIZE) { 1109 err = dt_print_quantize(dtp, fp, addr, size, normal); 1110 goto nextrec; 1111 } 1112 1113 if (act == DTRACEAGG_LQUANTIZE) { 1114 err = dt_print_lquantize(dtp, fp, addr, size, normal); 1115 goto nextrec; 1116 } 1117 1118 if (act == DTRACEAGG_AVG) { 1119 err = dt_print_average(dtp, fp, addr, size, normal); 1120 goto nextrec; 1121 } 1122 1123 switch (size) { 1124 case sizeof (uint64_t): 1125 err = dt_printf(dtp, fp, " %16lld", 1126 /* LINTED - alignment */ 1127 (long long)*((uint64_t *)addr) / normal); 1128 break; 1129 case sizeof (uint32_t): 1130 /* LINTED - alignment */ 1131 err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) / 1132 (uint32_t)normal); 1133 break; 1134 case sizeof (uint16_t): 1135 /* LINTED - alignment */ 1136 err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) / 1137 (uint32_t)normal); 1138 break; 1139 case sizeof (uint8_t): 1140 err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) / 1141 (uint32_t)normal); 1142 break; 1143 default: 1144 err = dt_print_bytes(dtp, fp, addr, size, 50, 0); 1145 break; 1146 } 1147 1148 nextrec: 1149 if (dt_buffered_flush(dtp, NULL, rec, aggdata) < 0) 1150 return (-1); 1151 } 1152 1153 if (err >= 0) 1154 err = dt_printf(dtp, fp, "\n"); 1155 1156 if (dt_buffered_flush(dtp, NULL, NULL, aggdata) < 0) 1157 return (-1); 1158 1159 if (!pd->dtpa_allunprint) 1160 agg->dtagd_flags |= DTRACE_AGD_PRINTED; 1161 1162 return (err < 0 ? -1 : 0); 1163 } 1164 1165 1166 int 1167 dt_setopt(dtrace_hdl_t *dtp, const dtrace_probedata_t *data, 1168 const char *option, const char *value) 1169 { 1170 int len, rval; 1171 char *msg; 1172 const char *errstr; 1173 dtrace_setoptdata_t optdata; 1174 1175 bzero(&optdata, sizeof (optdata)); 1176 (void) dtrace_getopt(dtp, option, &optdata.dtsda_oldval); 1177 1178 if (dtrace_setopt(dtp, option, value) == 0) { 1179 (void) dtrace_getopt(dtp, option, &optdata.dtsda_newval); 1180 optdata.dtsda_probe = data; 1181 optdata.dtsda_option = option; 1182 optdata.dtsda_handle = dtp; 1183 1184 if ((rval = dt_handle_setopt(dtp, &optdata)) != 0) 1185 return (rval); 1186 1187 return (0); 1188 } 1189 1190 errstr = dtrace_errmsg(dtp, dtrace_errno(dtp)); 1191 len = strlen(option) + strlen(value) + strlen(errstr) + 80; 1192 msg = alloca(len); 1193 1194 (void) snprintf(msg, len, "couldn't set option \"%s\" to \"%s\": %s\n", 1195 option, value, errstr); 1196 1197 if ((rval = dt_handle_liberr(dtp, data, msg)) == 0) 1198 return (0); 1199 1200 return (rval); 1201 } 1202 1203 static int 1204 dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf, 1205 dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc, void *arg) 1206 { 1207 dtrace_epid_t id; 1208 size_t offs, start = buf->dtbd_oldest, end = buf->dtbd_size; 1209 int flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET); 1210 int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET); 1211 int rval, i, n; 1212 dtrace_epid_t last = DTRACE_EPIDNONE; 1213 dtrace_probedata_t data; 1214 uint64_t drops; 1215 caddr_t addr; 1216 1217 bzero(&data, sizeof (data)); 1218 data.dtpda_handle = dtp; 1219 data.dtpda_cpu = cpu; 1220 1221 again: 1222 for (offs = start; offs < end; ) { 1223 dtrace_eprobedesc_t *epd; 1224 1225 /* 1226 * We're guaranteed to have an ID. 1227 */ 1228 id = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs); 1229 1230 if (id == DTRACE_EPIDNONE) { 1231 /* 1232 * This is filler to assure proper alignment of the 1233 * next record; we simply ignore it. 1234 */ 1235 offs += sizeof (id); 1236 continue; 1237 } 1238 1239 if ((rval = dt_epid_lookup(dtp, id, &data.dtpda_edesc, 1240 &data.dtpda_pdesc)) != 0) 1241 return (rval); 1242 1243 epd = data.dtpda_edesc; 1244 data.dtpda_data = buf->dtbd_data + offs; 1245 1246 if (data.dtpda_edesc->dtepd_uarg != DT_ECB_DEFAULT) { 1247 rval = dt_handle(dtp, &data); 1248 1249 if (rval == DTRACE_CONSUME_NEXT) 1250 goto nextepid; 1251 1252 if (rval == DTRACE_CONSUME_ERROR) 1253 return (-1); 1254 } 1255 1256 if (flow) 1257 (void) dt_flowindent(dtp, &data, last, buf, offs); 1258 1259 rval = (*efunc)(&data, arg); 1260 1261 if (flow) { 1262 if (data.dtpda_flow == DTRACEFLOW_ENTRY) 1263 data.dtpda_indent += 2; 1264 } 1265 1266 if (rval == DTRACE_CONSUME_NEXT) 1267 goto nextepid; 1268 1269 if (rval == DTRACE_CONSUME_ABORT) 1270 return (dt_set_errno(dtp, EDT_DIRABORT)); 1271 1272 if (rval != DTRACE_CONSUME_THIS) 1273 return (dt_set_errno(dtp, EDT_BADRVAL)); 1274 1275 for (i = 0; i < epd->dtepd_nrecs; i++) { 1276 dtrace_recdesc_t *rec = &epd->dtepd_rec[i]; 1277 dtrace_actkind_t act = rec->dtrd_action; 1278 1279 data.dtpda_data = buf->dtbd_data + offs + 1280 rec->dtrd_offset; 1281 addr = data.dtpda_data; 1282 1283 if (act == DTRACEACT_LIBACT) { 1284 uint64_t arg = rec->dtrd_arg; 1285 dtrace_aggvarid_t id; 1286 1287 switch (arg) { 1288 case DT_ACT_CLEAR: 1289 /* LINTED - alignment */ 1290 id = *((dtrace_aggvarid_t *)addr); 1291 (void) dtrace_aggregate_walk(dtp, 1292 dt_clear_agg, &id); 1293 continue; 1294 1295 case DT_ACT_DENORMALIZE: 1296 /* LINTED - alignment */ 1297 id = *((dtrace_aggvarid_t *)addr); 1298 (void) dtrace_aggregate_walk(dtp, 1299 dt_denormalize_agg, &id); 1300 continue; 1301 1302 case DT_ACT_FTRUNCATE: 1303 if (fp == NULL) 1304 continue; 1305 1306 (void) fflush(fp); 1307 (void) ftruncate(fileno(fp), 0); 1308 (void) fseeko(fp, 0, SEEK_SET); 1309 continue; 1310 1311 case DT_ACT_NORMALIZE: 1312 if (i == epd->dtepd_nrecs - 1) 1313 return (dt_set_errno(dtp, 1314 EDT_BADNORMAL)); 1315 1316 if (dt_normalize(dtp, 1317 buf->dtbd_data + offs, rec) != 0) 1318 return (-1); 1319 1320 i++; 1321 continue; 1322 1323 case DT_ACT_SETOPT: { 1324 uint64_t *opts = dtp->dt_options; 1325 dtrace_recdesc_t *valrec; 1326 uint32_t valsize; 1327 caddr_t val; 1328 int rv; 1329 1330 if (i == epd->dtepd_nrecs - 1) { 1331 return (dt_set_errno(dtp, 1332 EDT_BADSETOPT)); 1333 } 1334 1335 valrec = &epd->dtepd_rec[++i]; 1336 valsize = valrec->dtrd_size; 1337 1338 if (valrec->dtrd_action != act || 1339 valrec->dtrd_arg != arg) { 1340 return (dt_set_errno(dtp, 1341 EDT_BADSETOPT)); 1342 } 1343 1344 if (valsize > sizeof (uint64_t)) { 1345 val = buf->dtbd_data + offs + 1346 valrec->dtrd_offset; 1347 } else { 1348 val = "1"; 1349 } 1350 1351 rv = dt_setopt(dtp, &data, addr, val); 1352 1353 if (rv != 0) 1354 return (-1); 1355 1356 flow = (opts[DTRACEOPT_FLOWINDENT] != 1357 DTRACEOPT_UNSET); 1358 quiet = (opts[DTRACEOPT_QUIET] != 1359 DTRACEOPT_UNSET); 1360 1361 continue; 1362 } 1363 1364 case DT_ACT_TRUNC: 1365 if (i == epd->dtepd_nrecs - 1) 1366 return (dt_set_errno(dtp, 1367 EDT_BADTRUNC)); 1368 1369 if (dt_trunc(dtp, 1370 buf->dtbd_data + offs, rec) != 0) 1371 return (-1); 1372 1373 i++; 1374 continue; 1375 1376 default: 1377 continue; 1378 } 1379 } 1380 1381 rval = (*rfunc)(&data, rec, arg); 1382 1383 if (rval == DTRACE_CONSUME_NEXT) 1384 continue; 1385 1386 if (rval == DTRACE_CONSUME_ABORT) 1387 return (dt_set_errno(dtp, EDT_DIRABORT)); 1388 1389 if (rval != DTRACE_CONSUME_THIS) 1390 return (dt_set_errno(dtp, EDT_BADRVAL)); 1391 1392 if (act == DTRACEACT_STACK) { 1393 int depth = rec->dtrd_arg; 1394 1395 if (dt_print_stack(dtp, fp, NULL, addr, depth, 1396 rec->dtrd_size / depth) < 0) 1397 return (-1); 1398 goto nextrec; 1399 } 1400 1401 if (act == DTRACEACT_USTACK || 1402 act == DTRACEACT_JSTACK) { 1403 if (dt_print_ustack(dtp, fp, NULL, 1404 addr, rec->dtrd_arg) < 0) 1405 return (-1); 1406 goto nextrec; 1407 } 1408 1409 if (act == DTRACEACT_SYM) { 1410 if (dt_print_sym(dtp, fp, NULL, addr) < 0) 1411 return (-1); 1412 goto nextrec; 1413 } 1414 1415 if (act == DTRACEACT_MOD) { 1416 if (dt_print_mod(dtp, fp, NULL, addr) < 0) 1417 return (-1); 1418 goto nextrec; 1419 } 1420 1421 if (act == DTRACEACT_USYM || act == DTRACEACT_UADDR) { 1422 if (dt_print_usym(dtp, fp, addr, act) < 0) 1423 return (-1); 1424 goto nextrec; 1425 } 1426 1427 if (act == DTRACEACT_UMOD) { 1428 if (dt_print_umod(dtp, fp, NULL, addr) < 0) 1429 return (-1); 1430 goto nextrec; 1431 } 1432 1433 if (DTRACEACT_ISPRINTFLIKE(act)) { 1434 void *fmtdata; 1435 int (*func)(dtrace_hdl_t *, FILE *, void *, 1436 const dtrace_probedata_t *, 1437 const dtrace_recdesc_t *, uint_t, 1438 const void *buf, size_t); 1439 1440 if ((fmtdata = dt_format_lookup(dtp, 1441 rec->dtrd_format)) == NULL) 1442 goto nofmt; 1443 1444 switch (act) { 1445 case DTRACEACT_PRINTF: 1446 func = dtrace_fprintf; 1447 break; 1448 case DTRACEACT_PRINTA: 1449 func = dtrace_fprinta; 1450 break; 1451 case DTRACEACT_SYSTEM: 1452 func = dtrace_system; 1453 break; 1454 case DTRACEACT_FREOPEN: 1455 func = dtrace_freopen; 1456 break; 1457 } 1458 1459 n = (*func)(dtp, fp, fmtdata, &data, 1460 rec, epd->dtepd_nrecs - i, 1461 (uchar_t *)buf->dtbd_data + offs, 1462 buf->dtbd_size - offs); 1463 1464 if (n < 0) 1465 return (-1); /* errno is set for us */ 1466 1467 if (n > 0) 1468 i += n - 1; 1469 goto nextrec; 1470 } 1471 1472 nofmt: 1473 if (act == DTRACEACT_PRINTA) { 1474 dt_print_aggdata_t pd; 1475 1476 bzero(&pd, sizeof (pd)); 1477 pd.dtpa_dtp = dtp; 1478 pd.dtpa_fp = fp; 1479 /* LINTED - alignment */ 1480 pd.dtpa_id = *((dtrace_aggvarid_t *)addr); 1481 1482 if (dt_printf(dtp, fp, "\n") < 0 || 1483 dtrace_aggregate_walk_valsorted(dtp, 1484 dt_print_agg, &pd) < 0) 1485 return (-1); 1486 1487 goto nextrec; 1488 } 1489 1490 switch (rec->dtrd_size) { 1491 case sizeof (uint64_t): 1492 n = dt_printf(dtp, fp, 1493 quiet ? "%lld" : " %16lld", 1494 /* LINTED - alignment */ 1495 *((unsigned long long *)addr)); 1496 break; 1497 case sizeof (uint32_t): 1498 n = dt_printf(dtp, fp, quiet ? "%d" : " %8d", 1499 /* LINTED - alignment */ 1500 *((uint32_t *)addr)); 1501 break; 1502 case sizeof (uint16_t): 1503 n = dt_printf(dtp, fp, quiet ? "%d" : " %5d", 1504 /* LINTED - alignment */ 1505 *((uint16_t *)addr)); 1506 break; 1507 case sizeof (uint8_t): 1508 n = dt_printf(dtp, fp, quiet ? "%d" : " %3d", 1509 *((uint8_t *)addr)); 1510 break; 1511 default: 1512 n = dt_print_bytes(dtp, fp, addr, 1513 rec->dtrd_size, 33, quiet); 1514 break; 1515 } 1516 1517 if (n < 0) 1518 return (-1); /* errno is set for us */ 1519 1520 nextrec: 1521 if (dt_buffered_flush(dtp, &data, rec, NULL) < 0) 1522 return (-1); /* errno is set for us */ 1523 } 1524 1525 /* 1526 * Call the record callback with a NULL record to indicate 1527 * that we're done processing this EPID. 1528 */ 1529 rval = (*rfunc)(&data, NULL, arg); 1530 nextepid: 1531 offs += epd->dtepd_size; 1532 last = id; 1533 } 1534 1535 if (buf->dtbd_oldest != 0 && start == buf->dtbd_oldest) { 1536 end = buf->dtbd_oldest; 1537 start = 0; 1538 goto again; 1539 } 1540 1541 if ((drops = buf->dtbd_drops) == 0) 1542 return (0); 1543 1544 /* 1545 * Explicitly zero the drops to prevent us from processing them again. 1546 */ 1547 buf->dtbd_drops = 0; 1548 1549 return (dt_handle_cpudrop(dtp, cpu, DTRACEDROP_PRINCIPAL, drops)); 1550 } 1551 1552 typedef struct dt_begin { 1553 dtrace_consume_probe_f *dtbgn_probefunc; 1554 dtrace_consume_rec_f *dtbgn_recfunc; 1555 void *dtbgn_arg; 1556 dtrace_handle_err_f *dtbgn_errhdlr; 1557 void *dtbgn_errarg; 1558 int dtbgn_beginonly; 1559 } dt_begin_t; 1560 1561 static int 1562 dt_consume_begin_probe(const dtrace_probedata_t *data, void *arg) 1563 { 1564 dt_begin_t *begin = (dt_begin_t *)arg; 1565 dtrace_probedesc_t *pd = data->dtpda_pdesc; 1566 1567 int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0); 1568 int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0); 1569 1570 if (begin->dtbgn_beginonly) { 1571 if (!(r1 && r2)) 1572 return (DTRACE_CONSUME_NEXT); 1573 } else { 1574 if (r1 && r2) 1575 return (DTRACE_CONSUME_NEXT); 1576 } 1577 1578 /* 1579 * We have a record that we're interested in. Now call the underlying 1580 * probe function... 1581 */ 1582 return (begin->dtbgn_probefunc(data, begin->dtbgn_arg)); 1583 } 1584 1585 static int 1586 dt_consume_begin_record(const dtrace_probedata_t *data, 1587 const dtrace_recdesc_t *rec, void *arg) 1588 { 1589 dt_begin_t *begin = (dt_begin_t *)arg; 1590 1591 return (begin->dtbgn_recfunc(data, rec, begin->dtbgn_arg)); 1592 } 1593 1594 static int 1595 dt_consume_begin_error(const dtrace_errdata_t *data, void *arg) 1596 { 1597 dt_begin_t *begin = (dt_begin_t *)arg; 1598 dtrace_probedesc_t *pd = data->dteda_pdesc; 1599 1600 int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0); 1601 int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0); 1602 1603 if (begin->dtbgn_beginonly) { 1604 if (!(r1 && r2)) 1605 return (DTRACE_HANDLE_OK); 1606 } else { 1607 if (r1 && r2) 1608 return (DTRACE_HANDLE_OK); 1609 } 1610 1611 return (begin->dtbgn_errhdlr(data, begin->dtbgn_errarg)); 1612 } 1613 1614 static int 1615 dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf, 1616 dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg) 1617 { 1618 /* 1619 * There's this idea that the BEGIN probe should be processed before 1620 * everything else, and that the END probe should be processed after 1621 * anything else. In the common case, this is pretty easy to deal 1622 * with. However, a situation may arise where the BEGIN enabling and 1623 * END enabling are on the same CPU, and some enabling in the middle 1624 * occurred on a different CPU. To deal with this (blech!) we need to 1625 * consume the BEGIN buffer up until the end of the BEGIN probe, and 1626 * then set it aside. We will then process every other CPU, and then 1627 * we'll return to the BEGIN CPU and process the rest of the data 1628 * (which will inevitably include the END probe, if any). Making this 1629 * even more complicated (!) is the library's ERROR enabling. Because 1630 * this enabling is processed before we even get into the consume call 1631 * back, any ERROR firing would result in the library's ERROR enabling 1632 * being processed twice -- once in our first pass (for BEGIN probes), 1633 * and again in our second pass (for everything but BEGIN probes). To 1634 * deal with this, we interpose on the ERROR handler to assure that we 1635 * only process ERROR enablings induced by BEGIN enablings in the 1636 * first pass, and that we only process ERROR enablings _not_ induced 1637 * by BEGIN enablings in the second pass. 1638 */ 1639 dt_begin_t begin; 1640 processorid_t cpu = dtp->dt_beganon; 1641 dtrace_bufdesc_t nbuf; 1642 int rval, i; 1643 static int max_ncpus; 1644 dtrace_optval_t size; 1645 1646 dtp->dt_beganon = -1; 1647 1648 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1649 /* 1650 * We really don't expect this to fail, but it is at least 1651 * technically possible for this to fail with ENOENT. In this 1652 * case, we just drive on... 1653 */ 1654 if (errno == ENOENT) 1655 return (0); 1656 1657 return (dt_set_errno(dtp, errno)); 1658 } 1659 1660 if (!dtp->dt_stopped || buf->dtbd_cpu != dtp->dt_endedon) { 1661 /* 1662 * This is the simple case. We're either not stopped, or if 1663 * we are, we actually processed any END probes on another 1664 * CPU. We can simply consume this buffer and return. 1665 */ 1666 return (dt_consume_cpu(dtp, fp, cpu, buf, pf, rf, arg)); 1667 } 1668 1669 begin.dtbgn_probefunc = pf; 1670 begin.dtbgn_recfunc = rf; 1671 begin.dtbgn_arg = arg; 1672 begin.dtbgn_beginonly = 1; 1673 1674 /* 1675 * We need to interpose on the ERROR handler to be sure that we 1676 * only process ERRORs induced by BEGIN. 1677 */ 1678 begin.dtbgn_errhdlr = dtp->dt_errhdlr; 1679 begin.dtbgn_errarg = dtp->dt_errarg; 1680 dtp->dt_errhdlr = dt_consume_begin_error; 1681 dtp->dt_errarg = &begin; 1682 1683 rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe, 1684 dt_consume_begin_record, &begin); 1685 1686 dtp->dt_errhdlr = begin.dtbgn_errhdlr; 1687 dtp->dt_errarg = begin.dtbgn_errarg; 1688 1689 if (rval != 0) 1690 return (rval); 1691 1692 /* 1693 * Now allocate a new buffer. We'll use this to deal with every other 1694 * CPU. 1695 */ 1696 bzero(&nbuf, sizeof (dtrace_bufdesc_t)); 1697 (void) dtrace_getopt(dtp, "bufsize", &size); 1698 if ((nbuf.dtbd_data = malloc(size)) == NULL) 1699 return (dt_set_errno(dtp, EDT_NOMEM)); 1700 1701 if (max_ncpus == 0) 1702 max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1; 1703 1704 for (i = 0; i < max_ncpus; i++) { 1705 nbuf.dtbd_cpu = i; 1706 1707 if (i == cpu) 1708 continue; 1709 1710 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &nbuf) == -1) { 1711 /* 1712 * If we failed with ENOENT, it may be because the 1713 * CPU was unconfigured -- this is okay. Any other 1714 * error, however, is unexpected. 1715 */ 1716 if (errno == ENOENT) 1717 continue; 1718 1719 free(nbuf.dtbd_data); 1720 1721 return (dt_set_errno(dtp, errno)); 1722 } 1723 1724 if ((rval = dt_consume_cpu(dtp, fp, 1725 i, &nbuf, pf, rf, arg)) != 0) { 1726 free(nbuf.dtbd_data); 1727 return (rval); 1728 } 1729 } 1730 1731 free(nbuf.dtbd_data); 1732 1733 /* 1734 * Okay -- we're done with the other buffers. Now we want to 1735 * reconsume the first buffer -- but this time we're looking for 1736 * everything _but_ BEGIN. And of course, in order to only consume 1737 * those ERRORs _not_ associated with BEGIN, we need to reinstall our 1738 * ERROR interposition function... 1739 */ 1740 begin.dtbgn_beginonly = 0; 1741 1742 assert(begin.dtbgn_errhdlr == dtp->dt_errhdlr); 1743 assert(begin.dtbgn_errarg == dtp->dt_errarg); 1744 dtp->dt_errhdlr = dt_consume_begin_error; 1745 dtp->dt_errarg = &begin; 1746 1747 rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe, 1748 dt_consume_begin_record, &begin); 1749 1750 dtp->dt_errhdlr = begin.dtbgn_errhdlr; 1751 dtp->dt_errarg = begin.dtbgn_errarg; 1752 1753 return (rval); 1754 } 1755 1756 int 1757 dtrace_consume(dtrace_hdl_t *dtp, FILE *fp, 1758 dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg) 1759 { 1760 dtrace_bufdesc_t *buf = &dtp->dt_buf; 1761 dtrace_optval_t size; 1762 static int max_ncpus; 1763 int i, rval; 1764 dtrace_optval_t interval = dtp->dt_options[DTRACEOPT_SWITCHRATE]; 1765 hrtime_t now = gethrtime(); 1766 1767 if (dtp->dt_lastswitch != 0) { 1768 if (now - dtp->dt_lastswitch < interval) 1769 return (0); 1770 1771 dtp->dt_lastswitch += interval; 1772 } else { 1773 dtp->dt_lastswitch = now; 1774 } 1775 1776 if (!dtp->dt_active) 1777 return (dt_set_errno(dtp, EINVAL)); 1778 1779 if (max_ncpus == 0) 1780 max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1; 1781 1782 if (pf == NULL) 1783 pf = (dtrace_consume_probe_f *)dt_nullprobe; 1784 1785 if (rf == NULL) 1786 rf = (dtrace_consume_rec_f *)dt_nullrec; 1787 1788 if (buf->dtbd_data == NULL) { 1789 (void) dtrace_getopt(dtp, "bufsize", &size); 1790 if ((buf->dtbd_data = malloc(size)) == NULL) 1791 return (dt_set_errno(dtp, EDT_NOMEM)); 1792 1793 buf->dtbd_size = size; 1794 } 1795 1796 /* 1797 * If we have just begun, we want to first process the CPU that 1798 * executed the BEGIN probe (if any). 1799 */ 1800 if (dtp->dt_active && dtp->dt_beganon != -1) { 1801 buf->dtbd_cpu = dtp->dt_beganon; 1802 if ((rval = dt_consume_begin(dtp, fp, buf, pf, rf, arg)) != 0) 1803 return (rval); 1804 } 1805 1806 for (i = 0; i < max_ncpus; i++) { 1807 buf->dtbd_cpu = i; 1808 1809 /* 1810 * If we have stopped, we want to process the CPU on which the 1811 * END probe was processed only _after_ we have processed 1812 * everything else. 1813 */ 1814 if (dtp->dt_stopped && (i == dtp->dt_endedon)) 1815 continue; 1816 1817 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1818 /* 1819 * If we failed with ENOENT, it may be because the 1820 * CPU was unconfigured -- this is okay. Any other 1821 * error, however, is unexpected. 1822 */ 1823 if (errno == ENOENT) 1824 continue; 1825 1826 return (dt_set_errno(dtp, errno)); 1827 } 1828 1829 if ((rval = dt_consume_cpu(dtp, fp, i, buf, pf, rf, arg)) != 0) 1830 return (rval); 1831 } 1832 1833 if (!dtp->dt_stopped) 1834 return (0); 1835 1836 buf->dtbd_cpu = dtp->dt_endedon; 1837 1838 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1839 /* 1840 * This _really_ shouldn't fail, but it is strictly speaking 1841 * possible for this to return ENOENT if the CPU that called 1842 * the END enabling somehow managed to become unconfigured. 1843 * It's unclear how the user can possibly expect anything 1844 * rational to happen in this case -- the state has been thrown 1845 * out along with the unconfigured CPU -- so we'll just drive 1846 * on... 1847 */ 1848 if (errno == ENOENT) 1849 return (0); 1850 1851 return (dt_set_errno(dtp, errno)); 1852 } 1853 1854 return (dt_consume_cpu(dtp, fp, dtp->dt_endedon, buf, pf, rf, arg)); 1855 } 1856