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' && 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) { 665 str += strlen(str) + 1; 666 if (str - strbase >= strsize) 667 str = NULL; 668 } 669 } 670 671 if (P != NULL) { 672 dt_proc_unlock(dtp, P); 673 dt_proc_release(dtp, P); 674 } 675 676 return (err); 677 } 678 679 static int 680 dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act) 681 { 682 /* LINTED - alignment */ 683 uint64_t pid = ((uint64_t *)addr)[0]; 684 /* LINTED - alignment */ 685 uint64_t pc = ((uint64_t *)addr)[1]; 686 const char *format = " %-50s"; 687 char *s; 688 int n, len = 256; 689 690 if (act == DTRACEACT_USYM && dtp->dt_vector == NULL) { 691 struct ps_prochandle *P; 692 693 if ((P = dt_proc_grab(dtp, pid, 694 PGRAB_RDONLY | PGRAB_FORCE, 0)) != NULL) { 695 GElf_Sym sym; 696 697 dt_proc_lock(dtp, P); 698 699 if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0) 700 pc = sym.st_value; 701 702 dt_proc_unlock(dtp, P); 703 dt_proc_release(dtp, P); 704 } 705 } 706 707 do { 708 n = len; 709 s = alloca(n); 710 } while ((len = dtrace_uaddr2str(dtp, pid, pc, s, n)) >= n); 711 712 return (dt_printf(dtp, fp, format, s)); 713 } 714 715 int 716 dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 717 { 718 /* LINTED - alignment */ 719 uint64_t pid = ((uint64_t *)addr)[0]; 720 /* LINTED - alignment */ 721 uint64_t pc = ((uint64_t *)addr)[1]; 722 int err = 0; 723 724 char objname[PATH_MAX], c[PATH_MAX * 2]; 725 struct ps_prochandle *P; 726 727 if (format == NULL) 728 format = " %-50s"; 729 730 /* 731 * See the comment in dt_print_ustack() for the rationale for 732 * printing raw addresses in the vectored case. 733 */ 734 if (dtp->dt_vector == NULL) 735 P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0); 736 else 737 P = NULL; 738 739 if (P != NULL) 740 dt_proc_lock(dtp, P); /* lock handle while we perform lookups */ 741 742 if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != NULL) { 743 (void) snprintf(c, sizeof (c), "%s", dt_basename(objname)); 744 } else { 745 (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); 746 } 747 748 err = dt_printf(dtp, fp, format, c); 749 750 if (P != NULL) { 751 dt_proc_unlock(dtp, P); 752 dt_proc_release(dtp, P); 753 } 754 755 return (err); 756 } 757 758 static int 759 dt_print_sym(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 760 { 761 /* LINTED - alignment */ 762 uint64_t pc = *((uint64_t *)addr); 763 dtrace_syminfo_t dts; 764 GElf_Sym sym; 765 char c[PATH_MAX * 2]; 766 767 if (format == NULL) 768 format = " %-50s"; 769 770 if (dtrace_lookup_by_addr(dtp, pc, &sym, &dts) == 0) { 771 (void) snprintf(c, sizeof (c), "%s`%s", 772 dts.dts_object, dts.dts_name); 773 } else { 774 /* 775 * We'll repeat the lookup, but this time we'll specify a 776 * NULL GElf_Sym -- indicating that we're only interested in 777 * the containing module. 778 */ 779 if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) { 780 (void) snprintf(c, sizeof (c), "%s`0x%llx", 781 dts.dts_object, (u_longlong_t)pc); 782 } else { 783 (void) snprintf(c, sizeof (c), "0x%llx", 784 (u_longlong_t)pc); 785 } 786 } 787 788 if (dt_printf(dtp, fp, format, c) < 0) 789 return (-1); 790 791 return (0); 792 } 793 794 int 795 dt_print_mod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) 796 { 797 /* LINTED - alignment */ 798 uint64_t pc = *((uint64_t *)addr); 799 dtrace_syminfo_t dts; 800 char c[PATH_MAX * 2]; 801 802 if (format == NULL) 803 format = " %-50s"; 804 805 if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) { 806 (void) snprintf(c, sizeof (c), "%s", dts.dts_object); 807 } else { 808 (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); 809 } 810 811 if (dt_printf(dtp, fp, format, c) < 0) 812 return (-1); 813 814 return (0); 815 } 816 817 typedef struct dt_normal { 818 dtrace_aggvarid_t dtnd_id; 819 uint64_t dtnd_normal; 820 } dt_normal_t; 821 822 static int 823 dt_normalize_agg(const dtrace_aggdata_t *aggdata, void *arg) 824 { 825 dt_normal_t *normal = arg; 826 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 827 dtrace_aggvarid_t id = normal->dtnd_id; 828 uintptr_t data = (uintptr_t)aggdata->dtada_data; 829 830 if (agg->dtagd_nrecs == 0) 831 return (DTRACE_AGGWALK_NEXT); 832 833 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 834 return (DTRACE_AGGWALK_NEXT); 835 836 ((dtrace_aggdata_t *)aggdata)->dtada_normal = normal->dtnd_normal; 837 return (DTRACE_AGGWALK_NORMALIZE); 838 } 839 840 static int 841 dt_normalize(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec) 842 { 843 dt_normal_t normal; 844 caddr_t addr; 845 846 /* 847 * We (should) have two records: the aggregation ID followed by the 848 * normalization value. 849 */ 850 addr = base + rec->dtrd_offset; 851 852 if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) 853 return (dt_set_errno(dtp, EDT_BADNORMAL)); 854 855 /* LINTED - alignment */ 856 normal.dtnd_id = *((dtrace_aggvarid_t *)addr); 857 rec++; 858 859 if (rec->dtrd_action != DTRACEACT_LIBACT) 860 return (dt_set_errno(dtp, EDT_BADNORMAL)); 861 862 if (rec->dtrd_arg != DT_ACT_NORMALIZE) 863 return (dt_set_errno(dtp, EDT_BADNORMAL)); 864 865 addr = base + rec->dtrd_offset; 866 867 switch (rec->dtrd_size) { 868 case sizeof (uint64_t): 869 /* LINTED - alignment */ 870 normal.dtnd_normal = *((uint64_t *)addr); 871 break; 872 case sizeof (uint32_t): 873 /* LINTED - alignment */ 874 normal.dtnd_normal = *((uint32_t *)addr); 875 break; 876 case sizeof (uint16_t): 877 /* LINTED - alignment */ 878 normal.dtnd_normal = *((uint16_t *)addr); 879 break; 880 case sizeof (uint8_t): 881 normal.dtnd_normal = *((uint8_t *)addr); 882 break; 883 default: 884 return (dt_set_errno(dtp, EDT_BADNORMAL)); 885 } 886 887 (void) dtrace_aggregate_walk(dtp, dt_normalize_agg, &normal); 888 889 return (0); 890 } 891 892 static int 893 dt_denormalize_agg(const dtrace_aggdata_t *aggdata, void *arg) 894 { 895 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 896 dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); 897 uintptr_t data = (uintptr_t)aggdata->dtada_data; 898 899 if (agg->dtagd_nrecs == 0) 900 return (DTRACE_AGGWALK_NEXT); 901 902 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 903 return (DTRACE_AGGWALK_NEXT); 904 905 return (DTRACE_AGGWALK_DENORMALIZE); 906 } 907 908 static int 909 dt_clear_agg(const dtrace_aggdata_t *aggdata, void *arg) 910 { 911 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 912 dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); 913 uintptr_t data = (uintptr_t)aggdata->dtada_data; 914 915 if (agg->dtagd_nrecs == 0) 916 return (DTRACE_AGGWALK_NEXT); 917 918 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 919 return (DTRACE_AGGWALK_NEXT); 920 921 return (DTRACE_AGGWALK_CLEAR); 922 } 923 924 typedef struct dt_trunc { 925 dtrace_aggvarid_t dttd_id; 926 uint64_t dttd_remaining; 927 } dt_trunc_t; 928 929 static int 930 dt_trunc_agg(const dtrace_aggdata_t *aggdata, void *arg) 931 { 932 dt_trunc_t *trunc = arg; 933 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 934 dtrace_aggvarid_t id = trunc->dttd_id; 935 uintptr_t data = (uintptr_t)aggdata->dtada_data; 936 937 if (agg->dtagd_nrecs == 0) 938 return (DTRACE_AGGWALK_NEXT); 939 940 if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) 941 return (DTRACE_AGGWALK_NEXT); 942 943 if (trunc->dttd_remaining == 0) 944 return (DTRACE_AGGWALK_REMOVE); 945 946 trunc->dttd_remaining--; 947 return (DTRACE_AGGWALK_NEXT); 948 } 949 950 static int 951 dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec) 952 { 953 dt_trunc_t trunc; 954 caddr_t addr; 955 int64_t remaining; 956 int (*func)(dtrace_hdl_t *, dtrace_aggregate_f *, void *); 957 958 /* 959 * We (should) have two records: the aggregation ID followed by the 960 * number of aggregation entries after which the aggregation is to be 961 * truncated. 962 */ 963 addr = base + rec->dtrd_offset; 964 965 if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) 966 return (dt_set_errno(dtp, EDT_BADTRUNC)); 967 968 /* LINTED - alignment */ 969 trunc.dttd_id = *((dtrace_aggvarid_t *)addr); 970 rec++; 971 972 if (rec->dtrd_action != DTRACEACT_LIBACT) 973 return (dt_set_errno(dtp, EDT_BADTRUNC)); 974 975 if (rec->dtrd_arg != DT_ACT_TRUNC) 976 return (dt_set_errno(dtp, EDT_BADTRUNC)); 977 978 addr = base + rec->dtrd_offset; 979 980 switch (rec->dtrd_size) { 981 case sizeof (uint64_t): 982 /* LINTED - alignment */ 983 remaining = *((int64_t *)addr); 984 break; 985 case sizeof (uint32_t): 986 /* LINTED - alignment */ 987 remaining = *((int32_t *)addr); 988 break; 989 case sizeof (uint16_t): 990 /* LINTED - alignment */ 991 remaining = *((int16_t *)addr); 992 break; 993 case sizeof (uint8_t): 994 remaining = *((int8_t *)addr); 995 break; 996 default: 997 return (dt_set_errno(dtp, EDT_BADNORMAL)); 998 } 999 1000 if (remaining < 0) { 1001 func = dtrace_aggregate_walk_valsorted; 1002 remaining = -remaining; 1003 } else { 1004 func = dtrace_aggregate_walk_valrevsorted; 1005 } 1006 1007 assert(remaining >= 0); 1008 trunc.dttd_remaining = remaining; 1009 1010 (void) func(dtp, dt_trunc_agg, &trunc); 1011 1012 return (0); 1013 } 1014 1015 int 1016 dt_print_agg(const dtrace_aggdata_t *aggdata, void *arg) 1017 { 1018 int i, err = 0; 1019 dt_print_aggdata_t *pd = arg; 1020 dtrace_aggdesc_t *agg = aggdata->dtada_desc; 1021 FILE *fp = pd->dtpa_fp; 1022 dtrace_hdl_t *dtp = pd->dtpa_dtp; 1023 dtrace_aggvarid_t aggvarid = pd->dtpa_id; 1024 uintptr_t data = (uintptr_t)aggdata->dtada_data; 1025 1026 if (pd->dtpa_allunprint) { 1027 if (agg->dtagd_flags & DTRACE_AGD_PRINTED) 1028 return (0); 1029 } else { 1030 /* 1031 * If we're not printing all unprinted aggregations, then the 1032 * aggregation variable ID denotes a specific aggregation 1033 * variable that we should print -- skip any other aggregations 1034 * that we encounter. 1035 */ 1036 if (agg->dtagd_nrecs == 0) 1037 return (0); 1038 1039 if (aggvarid != *(dtrace_aggvarid_t *)(data + 1040 agg->dtagd_rec[0].dtrd_offset)) 1041 return (0); 1042 } 1043 1044 /* 1045 * Iterate over each record description, printing the traced data, 1046 * skipping the first datum (the tuple member created by the compiler). 1047 */ 1048 for (i = 1; err >= 0 && i < agg->dtagd_nrecs; i++) { 1049 dtrace_recdesc_t *rec = &agg->dtagd_rec[i]; 1050 dtrace_actkind_t act = rec->dtrd_action; 1051 caddr_t addr = aggdata->dtada_data + rec->dtrd_offset; 1052 size_t size = rec->dtrd_size; 1053 uint64_t normal; 1054 1055 normal = DTRACEACT_ISAGG(act) ? aggdata->dtada_normal : 1; 1056 1057 if (act == DTRACEACT_STACK) { 1058 err = dt_print_stack(dtp, fp, NULL, addr, 1059 rec->dtrd_arg, rec->dtrd_size / rec->dtrd_arg); 1060 goto nextrec; 1061 } 1062 1063 if (act == DTRACEACT_USTACK || act == DTRACEACT_JSTACK) { 1064 err = dt_print_ustack(dtp, fp, NULL, addr, 1065 rec->dtrd_arg); 1066 goto nextrec; 1067 } 1068 1069 if (act == DTRACEACT_USYM || act == DTRACEACT_UADDR) { 1070 err = dt_print_usym(dtp, fp, addr, act); 1071 goto nextrec; 1072 } 1073 1074 if (act == DTRACEACT_UMOD) { 1075 err = dt_print_umod(dtp, fp, NULL, addr); 1076 goto nextrec; 1077 } 1078 1079 if (act == DTRACEACT_SYM) { 1080 err = dt_print_sym(dtp, fp, NULL, addr); 1081 goto nextrec; 1082 } 1083 1084 if (act == DTRACEACT_MOD) { 1085 err = dt_print_mod(dtp, fp, NULL, addr); 1086 goto nextrec; 1087 } 1088 1089 if (act == DTRACEAGG_QUANTIZE) { 1090 err = dt_print_quantize(dtp, fp, addr, size, normal); 1091 goto nextrec; 1092 } 1093 1094 if (act == DTRACEAGG_LQUANTIZE) { 1095 err = dt_print_lquantize(dtp, fp, addr, size, normal); 1096 goto nextrec; 1097 } 1098 1099 if (act == DTRACEAGG_AVG) { 1100 err = dt_print_average(dtp, fp, addr, size, normal); 1101 goto nextrec; 1102 } 1103 1104 switch (size) { 1105 case sizeof (uint64_t): 1106 err = dt_printf(dtp, fp, " %16lld", 1107 /* LINTED - alignment */ 1108 (long long)*((uint64_t *)addr) / normal); 1109 break; 1110 case sizeof (uint32_t): 1111 /* LINTED - alignment */ 1112 err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) / 1113 (uint32_t)normal); 1114 break; 1115 case sizeof (uint16_t): 1116 /* LINTED - alignment */ 1117 err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) / 1118 (uint32_t)normal); 1119 break; 1120 case sizeof (uint8_t): 1121 err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) / 1122 (uint32_t)normal); 1123 break; 1124 default: 1125 err = dt_print_bytes(dtp, fp, addr, size, 50, 0); 1126 break; 1127 } 1128 1129 nextrec: 1130 if (dt_buffered_flush(dtp, NULL, rec, aggdata) < 0) 1131 return (-1); 1132 } 1133 1134 if (err >= 0) 1135 err = dt_printf(dtp, fp, "\n"); 1136 1137 if (dt_buffered_flush(dtp, NULL, NULL, aggdata) < 0) 1138 return (-1); 1139 1140 if (!pd->dtpa_allunprint) 1141 agg->dtagd_flags |= DTRACE_AGD_PRINTED; 1142 1143 return (err < 0 ? -1 : 0); 1144 } 1145 1146 1147 int 1148 dt_setopt(dtrace_hdl_t *dtp, const dtrace_probedata_t *data, 1149 const char *option, const char *value) 1150 { 1151 int len, rval; 1152 char *msg; 1153 const char *errstr; 1154 dtrace_setoptdata_t optdata; 1155 1156 bzero(&optdata, sizeof (optdata)); 1157 (void) dtrace_getopt(dtp, option, &optdata.dtsda_oldval); 1158 1159 if (dtrace_setopt(dtp, option, value) == 0) { 1160 (void) dtrace_getopt(dtp, option, &optdata.dtsda_newval); 1161 optdata.dtsda_probe = data; 1162 optdata.dtsda_option = option; 1163 optdata.dtsda_handle = dtp; 1164 1165 if ((rval = dt_handle_setopt(dtp, &optdata)) != 0) 1166 return (rval); 1167 1168 return (0); 1169 } 1170 1171 errstr = dtrace_errmsg(dtp, dtrace_errno(dtp)); 1172 len = strlen(option) + strlen(value) + strlen(errstr) + 80; 1173 msg = alloca(len); 1174 1175 (void) snprintf(msg, len, "couldn't set option \"%s\" to \"%s\": %s\n", 1176 option, value, errstr); 1177 1178 if ((rval = dt_handle_liberr(dtp, data, msg)) == 0) 1179 return (0); 1180 1181 return (rval); 1182 } 1183 1184 static int 1185 dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf, 1186 dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc, void *arg) 1187 { 1188 dtrace_epid_t id; 1189 size_t offs, start = buf->dtbd_oldest, end = buf->dtbd_size; 1190 int flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET); 1191 int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET); 1192 int rval, i, n; 1193 dtrace_epid_t last = DTRACE_EPIDNONE; 1194 dtrace_probedata_t data; 1195 uint64_t drops; 1196 caddr_t addr; 1197 1198 bzero(&data, sizeof (data)); 1199 data.dtpda_handle = dtp; 1200 data.dtpda_cpu = cpu; 1201 1202 again: 1203 for (offs = start; offs < end; ) { 1204 dtrace_eprobedesc_t *epd; 1205 1206 /* 1207 * We're guaranteed to have an ID. 1208 */ 1209 id = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs); 1210 1211 if (id == DTRACE_EPIDNONE) { 1212 /* 1213 * This is filler to assure proper alignment of the 1214 * next record; we simply ignore it. 1215 */ 1216 offs += sizeof (id); 1217 continue; 1218 } 1219 1220 if ((rval = dt_epid_lookup(dtp, id, &data.dtpda_edesc, 1221 &data.dtpda_pdesc)) != 0) 1222 return (rval); 1223 1224 epd = data.dtpda_edesc; 1225 data.dtpda_data = buf->dtbd_data + offs; 1226 1227 if (data.dtpda_edesc->dtepd_uarg != DT_ECB_DEFAULT) { 1228 rval = dt_handle(dtp, &data); 1229 1230 if (rval == DTRACE_CONSUME_NEXT) 1231 goto nextepid; 1232 1233 if (rval == DTRACE_CONSUME_ERROR) 1234 return (-1); 1235 } 1236 1237 if (flow) 1238 (void) dt_flowindent(dtp, &data, last, buf, offs); 1239 1240 rval = (*efunc)(&data, arg); 1241 1242 if (flow) { 1243 if (data.dtpda_flow == DTRACEFLOW_ENTRY) 1244 data.dtpda_indent += 2; 1245 } 1246 1247 if (rval == DTRACE_CONSUME_NEXT) 1248 goto nextepid; 1249 1250 if (rval == DTRACE_CONSUME_ABORT) 1251 return (dt_set_errno(dtp, EDT_DIRABORT)); 1252 1253 if (rval != DTRACE_CONSUME_THIS) 1254 return (dt_set_errno(dtp, EDT_BADRVAL)); 1255 1256 for (i = 0; i < epd->dtepd_nrecs; i++) { 1257 dtrace_recdesc_t *rec = &epd->dtepd_rec[i]; 1258 dtrace_actkind_t act = rec->dtrd_action; 1259 1260 data.dtpda_data = buf->dtbd_data + offs + 1261 rec->dtrd_offset; 1262 addr = data.dtpda_data; 1263 1264 if (act == DTRACEACT_LIBACT) { 1265 uint64_t arg = rec->dtrd_arg; 1266 dtrace_aggvarid_t id; 1267 1268 switch (arg) { 1269 case DT_ACT_CLEAR: 1270 /* LINTED - alignment */ 1271 id = *((dtrace_aggvarid_t *)addr); 1272 (void) dtrace_aggregate_walk(dtp, 1273 dt_clear_agg, &id); 1274 continue; 1275 1276 case DT_ACT_DENORMALIZE: 1277 /* LINTED - alignment */ 1278 id = *((dtrace_aggvarid_t *)addr); 1279 (void) dtrace_aggregate_walk(dtp, 1280 dt_denormalize_agg, &id); 1281 continue; 1282 1283 case DT_ACT_FTRUNCATE: 1284 if (fp == NULL) 1285 continue; 1286 1287 (void) fflush(fp); 1288 (void) ftruncate(fileno(fp), 0); 1289 (void) fseeko(fp, 0, SEEK_SET); 1290 continue; 1291 1292 case DT_ACT_NORMALIZE: 1293 if (i == epd->dtepd_nrecs - 1) 1294 return (dt_set_errno(dtp, 1295 EDT_BADNORMAL)); 1296 1297 if (dt_normalize(dtp, 1298 buf->dtbd_data + offs, rec) != 0) 1299 return (-1); 1300 1301 i++; 1302 continue; 1303 1304 case DT_ACT_SETOPT: { 1305 uint64_t *opts = dtp->dt_options; 1306 dtrace_recdesc_t *valrec; 1307 uint32_t valsize; 1308 caddr_t val; 1309 int rv; 1310 1311 if (i == epd->dtepd_nrecs - 1) { 1312 return (dt_set_errno(dtp, 1313 EDT_BADSETOPT)); 1314 } 1315 1316 valrec = &epd->dtepd_rec[++i]; 1317 valsize = valrec->dtrd_size; 1318 1319 if (valrec->dtrd_action != act || 1320 valrec->dtrd_arg != arg) { 1321 return (dt_set_errno(dtp, 1322 EDT_BADSETOPT)); 1323 } 1324 1325 if (valsize > sizeof (uint64_t)) { 1326 val = buf->dtbd_data + offs + 1327 valrec->dtrd_offset; 1328 } else { 1329 val = "1"; 1330 } 1331 1332 rv = dt_setopt(dtp, &data, addr, val); 1333 1334 if (rv != 0) 1335 return (-1); 1336 1337 flow = (opts[DTRACEOPT_FLOWINDENT] != 1338 DTRACEOPT_UNSET); 1339 quiet = (opts[DTRACEOPT_QUIET] != 1340 DTRACEOPT_UNSET); 1341 1342 continue; 1343 } 1344 1345 case DT_ACT_TRUNC: 1346 if (i == epd->dtepd_nrecs - 1) 1347 return (dt_set_errno(dtp, 1348 EDT_BADTRUNC)); 1349 1350 if (dt_trunc(dtp, 1351 buf->dtbd_data + offs, rec) != 0) 1352 return (-1); 1353 1354 i++; 1355 continue; 1356 1357 default: 1358 continue; 1359 } 1360 } 1361 1362 rval = (*rfunc)(&data, rec, arg); 1363 1364 if (rval == DTRACE_CONSUME_NEXT) 1365 continue; 1366 1367 if (rval == DTRACE_CONSUME_ABORT) 1368 return (dt_set_errno(dtp, EDT_DIRABORT)); 1369 1370 if (rval != DTRACE_CONSUME_THIS) 1371 return (dt_set_errno(dtp, EDT_BADRVAL)); 1372 1373 if (act == DTRACEACT_STACK) { 1374 int depth = rec->dtrd_arg; 1375 1376 if (dt_print_stack(dtp, fp, NULL, addr, depth, 1377 rec->dtrd_size / depth) < 0) 1378 return (-1); 1379 goto nextrec; 1380 } 1381 1382 if (act == DTRACEACT_USTACK || 1383 act == DTRACEACT_JSTACK) { 1384 if (dt_print_ustack(dtp, fp, NULL, 1385 addr, rec->dtrd_arg) < 0) 1386 return (-1); 1387 goto nextrec; 1388 } 1389 1390 if (act == DTRACEACT_SYM) { 1391 if (dt_print_sym(dtp, fp, NULL, addr) < 0) 1392 return (-1); 1393 goto nextrec; 1394 } 1395 1396 if (act == DTRACEACT_MOD) { 1397 if (dt_print_mod(dtp, fp, NULL, addr) < 0) 1398 return (-1); 1399 goto nextrec; 1400 } 1401 1402 if (act == DTRACEACT_USYM || act == DTRACEACT_UADDR) { 1403 if (dt_print_usym(dtp, fp, addr, act) < 0) 1404 return (-1); 1405 goto nextrec; 1406 } 1407 1408 if (act == DTRACEACT_UMOD) { 1409 if (dt_print_umod(dtp, fp, NULL, addr) < 0) 1410 return (-1); 1411 goto nextrec; 1412 } 1413 1414 if (DTRACEACT_ISPRINTFLIKE(act)) { 1415 void *fmtdata; 1416 int (*func)(dtrace_hdl_t *, FILE *, void *, 1417 const dtrace_probedata_t *, 1418 const dtrace_recdesc_t *, uint_t, 1419 const void *buf, size_t); 1420 1421 if ((fmtdata = dt_format_lookup(dtp, 1422 rec->dtrd_format)) == NULL) 1423 goto nofmt; 1424 1425 switch (act) { 1426 case DTRACEACT_PRINTF: 1427 func = dtrace_fprintf; 1428 break; 1429 case DTRACEACT_PRINTA: 1430 func = dtrace_fprinta; 1431 break; 1432 case DTRACEACT_SYSTEM: 1433 func = dtrace_system; 1434 break; 1435 case DTRACEACT_FREOPEN: 1436 func = dtrace_freopen; 1437 break; 1438 } 1439 1440 n = (*func)(dtp, fp, fmtdata, &data, 1441 rec, epd->dtepd_nrecs - i, 1442 (uchar_t *)buf->dtbd_data + offs, 1443 buf->dtbd_size - offs); 1444 1445 if (n < 0) 1446 return (-1); /* errno is set for us */ 1447 1448 if (n > 0) 1449 i += n - 1; 1450 goto nextrec; 1451 } 1452 1453 nofmt: 1454 if (act == DTRACEACT_PRINTA) { 1455 dt_print_aggdata_t pd; 1456 1457 bzero(&pd, sizeof (pd)); 1458 pd.dtpa_dtp = dtp; 1459 pd.dtpa_fp = fp; 1460 /* LINTED - alignment */ 1461 pd.dtpa_id = *((dtrace_aggvarid_t *)addr); 1462 1463 if (dt_printf(dtp, fp, "\n") < 0 || 1464 dtrace_aggregate_walk_valsorted(dtp, 1465 dt_print_agg, &pd) < 0) 1466 return (-1); 1467 1468 goto nextrec; 1469 } 1470 1471 switch (rec->dtrd_size) { 1472 case sizeof (uint64_t): 1473 n = dt_printf(dtp, fp, 1474 quiet ? "%lld" : " %16lld", 1475 /* LINTED - alignment */ 1476 *((unsigned long long *)addr)); 1477 break; 1478 case sizeof (uint32_t): 1479 n = dt_printf(dtp, fp, quiet ? "%d" : " %8d", 1480 /* LINTED - alignment */ 1481 *((uint32_t *)addr)); 1482 break; 1483 case sizeof (uint16_t): 1484 n = dt_printf(dtp, fp, quiet ? "%d" : " %5d", 1485 /* LINTED - alignment */ 1486 *((uint16_t *)addr)); 1487 break; 1488 case sizeof (uint8_t): 1489 n = dt_printf(dtp, fp, quiet ? "%d" : " %3d", 1490 *((uint8_t *)addr)); 1491 break; 1492 default: 1493 n = dt_print_bytes(dtp, fp, addr, 1494 rec->dtrd_size, 33, quiet); 1495 break; 1496 } 1497 1498 if (n < 0) 1499 return (-1); /* errno is set for us */ 1500 1501 nextrec: 1502 if (dt_buffered_flush(dtp, &data, rec, NULL) < 0) 1503 return (-1); /* errno is set for us */ 1504 } 1505 1506 /* 1507 * Call the record callback with a NULL record to indicate 1508 * that we're done processing this EPID. 1509 */ 1510 rval = (*rfunc)(&data, NULL, arg); 1511 nextepid: 1512 offs += epd->dtepd_size; 1513 last = id; 1514 } 1515 1516 if (buf->dtbd_oldest != 0 && start == buf->dtbd_oldest) { 1517 end = buf->dtbd_oldest; 1518 start = 0; 1519 goto again; 1520 } 1521 1522 if ((drops = buf->dtbd_drops) == 0) 1523 return (0); 1524 1525 /* 1526 * Explicitly zero the drops to prevent us from processing them again. 1527 */ 1528 buf->dtbd_drops = 0; 1529 1530 return (dt_handle_cpudrop(dtp, cpu, DTRACEDROP_PRINCIPAL, drops)); 1531 } 1532 1533 typedef struct dt_begin { 1534 dtrace_consume_probe_f *dtbgn_probefunc; 1535 dtrace_consume_rec_f *dtbgn_recfunc; 1536 void *dtbgn_arg; 1537 dtrace_handle_err_f *dtbgn_errhdlr; 1538 void *dtbgn_errarg; 1539 int dtbgn_beginonly; 1540 } dt_begin_t; 1541 1542 static int 1543 dt_consume_begin_probe(const dtrace_probedata_t *data, void *arg) 1544 { 1545 dt_begin_t *begin = (dt_begin_t *)arg; 1546 dtrace_probedesc_t *pd = data->dtpda_pdesc; 1547 1548 int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0); 1549 int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0); 1550 1551 if (begin->dtbgn_beginonly) { 1552 if (!(r1 && r2)) 1553 return (DTRACE_CONSUME_NEXT); 1554 } else { 1555 if (r1 && r2) 1556 return (DTRACE_CONSUME_NEXT); 1557 } 1558 1559 /* 1560 * We have a record that we're interested in. Now call the underlying 1561 * probe function... 1562 */ 1563 return (begin->dtbgn_probefunc(data, begin->dtbgn_arg)); 1564 } 1565 1566 static int 1567 dt_consume_begin_record(const dtrace_probedata_t *data, 1568 const dtrace_recdesc_t *rec, void *arg) 1569 { 1570 dt_begin_t *begin = (dt_begin_t *)arg; 1571 1572 return (begin->dtbgn_recfunc(data, rec, begin->dtbgn_arg)); 1573 } 1574 1575 static int 1576 dt_consume_begin_error(const dtrace_errdata_t *data, void *arg) 1577 { 1578 dt_begin_t *begin = (dt_begin_t *)arg; 1579 dtrace_probedesc_t *pd = data->dteda_pdesc; 1580 1581 int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0); 1582 int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0); 1583 1584 if (begin->dtbgn_beginonly) { 1585 if (!(r1 && r2)) 1586 return (DTRACE_HANDLE_OK); 1587 } else { 1588 if (r1 && r2) 1589 return (DTRACE_HANDLE_OK); 1590 } 1591 1592 return (begin->dtbgn_errhdlr(data, begin->dtbgn_errarg)); 1593 } 1594 1595 static int 1596 dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf, 1597 dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg) 1598 { 1599 /* 1600 * There's this idea that the BEGIN probe should be processed before 1601 * everything else, and that the END probe should be processed after 1602 * anything else. In the common case, this is pretty easy to deal 1603 * with. However, a situation may arise where the BEGIN enabling and 1604 * END enabling are on the same CPU, and some enabling in the middle 1605 * occurred on a different CPU. To deal with this (blech!) we need to 1606 * consume the BEGIN buffer up until the end of the BEGIN probe, and 1607 * then set it aside. We will then process every other CPU, and then 1608 * we'll return to the BEGIN CPU and process the rest of the data 1609 * (which will inevitably include the END probe, if any). Making this 1610 * even more complicated (!) is the library's ERROR enabling. Because 1611 * this enabling is processed before we even get into the consume call 1612 * back, any ERROR firing would result in the library's ERROR enabling 1613 * being processed twice -- once in our first pass (for BEGIN probes), 1614 * and again in our second pass (for everything but BEGIN probes). To 1615 * deal with this, we interpose on the ERROR handler to assure that we 1616 * only process ERROR enablings induced by BEGIN enablings in the 1617 * first pass, and that we only process ERROR enablings _not_ induced 1618 * by BEGIN enablings in the second pass. 1619 */ 1620 dt_begin_t begin; 1621 processorid_t cpu = dtp->dt_beganon; 1622 dtrace_bufdesc_t nbuf; 1623 int rval, i; 1624 static int max_ncpus; 1625 dtrace_optval_t size; 1626 1627 dtp->dt_beganon = -1; 1628 1629 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1630 /* 1631 * We really don't expect this to fail, but it is at least 1632 * technically possible for this to fail with ENOENT. In this 1633 * case, we just drive on... 1634 */ 1635 if (errno == ENOENT) 1636 return (0); 1637 1638 return (dt_set_errno(dtp, errno)); 1639 } 1640 1641 if (!dtp->dt_stopped || buf->dtbd_cpu != dtp->dt_endedon) { 1642 /* 1643 * This is the simple case. We're either not stopped, or if 1644 * we are, we actually processed any END probes on another 1645 * CPU. We can simply consume this buffer and return. 1646 */ 1647 return (dt_consume_cpu(dtp, fp, cpu, buf, pf, rf, arg)); 1648 } 1649 1650 begin.dtbgn_probefunc = pf; 1651 begin.dtbgn_recfunc = rf; 1652 begin.dtbgn_arg = arg; 1653 begin.dtbgn_beginonly = 1; 1654 1655 /* 1656 * We need to interpose on the ERROR handler to be sure that we 1657 * only process ERRORs induced by BEGIN. 1658 */ 1659 begin.dtbgn_errhdlr = dtp->dt_errhdlr; 1660 begin.dtbgn_errarg = dtp->dt_errarg; 1661 dtp->dt_errhdlr = dt_consume_begin_error; 1662 dtp->dt_errarg = &begin; 1663 1664 rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe, 1665 dt_consume_begin_record, &begin); 1666 1667 dtp->dt_errhdlr = begin.dtbgn_errhdlr; 1668 dtp->dt_errarg = begin.dtbgn_errarg; 1669 1670 if (rval != 0) 1671 return (rval); 1672 1673 /* 1674 * Now allocate a new buffer. We'll use this to deal with every other 1675 * CPU. 1676 */ 1677 bzero(&nbuf, sizeof (dtrace_bufdesc_t)); 1678 (void) dtrace_getopt(dtp, "bufsize", &size); 1679 if ((nbuf.dtbd_data = malloc(size)) == NULL) 1680 return (dt_set_errno(dtp, EDT_NOMEM)); 1681 1682 if (max_ncpus == 0) 1683 max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1; 1684 1685 for (i = 0; i < max_ncpus; i++) { 1686 nbuf.dtbd_cpu = i; 1687 1688 if (i == cpu) 1689 continue; 1690 1691 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &nbuf) == -1) { 1692 /* 1693 * If we failed with ENOENT, it may be because the 1694 * CPU was unconfigured -- this is okay. Any other 1695 * error, however, is unexpected. 1696 */ 1697 if (errno == ENOENT) 1698 continue; 1699 1700 free(nbuf.dtbd_data); 1701 1702 return (dt_set_errno(dtp, errno)); 1703 } 1704 1705 if ((rval = dt_consume_cpu(dtp, fp, 1706 i, &nbuf, pf, rf, arg)) != 0) { 1707 free(nbuf.dtbd_data); 1708 return (rval); 1709 } 1710 } 1711 1712 free(nbuf.dtbd_data); 1713 1714 /* 1715 * Okay -- we're done with the other buffers. Now we want to 1716 * reconsume the first buffer -- but this time we're looking for 1717 * everything _but_ BEGIN. And of course, in order to only consume 1718 * those ERRORs _not_ associated with BEGIN, we need to reinstall our 1719 * ERROR interposition function... 1720 */ 1721 begin.dtbgn_beginonly = 0; 1722 1723 assert(begin.dtbgn_errhdlr == dtp->dt_errhdlr); 1724 assert(begin.dtbgn_errarg == dtp->dt_errarg); 1725 dtp->dt_errhdlr = dt_consume_begin_error; 1726 dtp->dt_errarg = &begin; 1727 1728 rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe, 1729 dt_consume_begin_record, &begin); 1730 1731 dtp->dt_errhdlr = begin.dtbgn_errhdlr; 1732 dtp->dt_errarg = begin.dtbgn_errarg; 1733 1734 return (rval); 1735 } 1736 1737 int 1738 dtrace_consume(dtrace_hdl_t *dtp, FILE *fp, 1739 dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg) 1740 { 1741 dtrace_bufdesc_t *buf = &dtp->dt_buf; 1742 dtrace_optval_t size; 1743 static int max_ncpus; 1744 int i, rval; 1745 dtrace_optval_t interval = dtp->dt_options[DTRACEOPT_SWITCHRATE]; 1746 hrtime_t now = gethrtime(); 1747 1748 if (dtp->dt_lastswitch != 0) { 1749 if (now - dtp->dt_lastswitch < interval) 1750 return (0); 1751 1752 dtp->dt_lastswitch += interval; 1753 } else { 1754 dtp->dt_lastswitch = now; 1755 } 1756 1757 if (!dtp->dt_active) 1758 return (dt_set_errno(dtp, EINVAL)); 1759 1760 if (max_ncpus == 0) 1761 max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1; 1762 1763 if (pf == NULL) 1764 pf = (dtrace_consume_probe_f *)dt_nullprobe; 1765 1766 if (rf == NULL) 1767 rf = (dtrace_consume_rec_f *)dt_nullrec; 1768 1769 if (buf->dtbd_data == NULL) { 1770 (void) dtrace_getopt(dtp, "bufsize", &size); 1771 if ((buf->dtbd_data = malloc(size)) == NULL) 1772 return (dt_set_errno(dtp, EDT_NOMEM)); 1773 1774 buf->dtbd_size = size; 1775 } 1776 1777 /* 1778 * If we have just begun, we want to first process the CPU that 1779 * executed the BEGIN probe (if any). 1780 */ 1781 if (dtp->dt_active && dtp->dt_beganon != -1) { 1782 buf->dtbd_cpu = dtp->dt_beganon; 1783 if ((rval = dt_consume_begin(dtp, fp, buf, pf, rf, arg)) != 0) 1784 return (rval); 1785 } 1786 1787 for (i = 0; i < max_ncpus; i++) { 1788 buf->dtbd_cpu = i; 1789 1790 /* 1791 * If we have stopped, we want to process the CPU on which the 1792 * END probe was processed only _after_ we have processed 1793 * everything else. 1794 */ 1795 if (dtp->dt_stopped && (i == dtp->dt_endedon)) 1796 continue; 1797 1798 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1799 /* 1800 * If we failed with ENOENT, it may be because the 1801 * CPU was unconfigured -- this is okay. Any other 1802 * error, however, is unexpected. 1803 */ 1804 if (errno == ENOENT) 1805 continue; 1806 1807 return (dt_set_errno(dtp, errno)); 1808 } 1809 1810 if ((rval = dt_consume_cpu(dtp, fp, i, buf, pf, rf, arg)) != 0) 1811 return (rval); 1812 } 1813 1814 if (!dtp->dt_stopped) 1815 return (0); 1816 1817 buf->dtbd_cpu = dtp->dt_endedon; 1818 1819 if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) { 1820 /* 1821 * This _really_ shouldn't fail, but it is strictly speaking 1822 * possible for this to return ENOENT if the CPU that called 1823 * the END enabling somehow managed to become unconfigured. 1824 * It's unclear how the user can possibly expect anything 1825 * rational to happen in this case -- the state has been thrown 1826 * out along with the unconfigured CPU -- so we'll just drive 1827 * on... 1828 */ 1829 if (errno == ENOENT) 1830 return (0); 1831 1832 return (dt_set_errno(dtp, errno)); 1833 } 1834 1835 return (dt_consume_cpu(dtp, fp, dtp->dt_endedon, buf, pf, rf, arg)); 1836 } 1837