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 <assert.h> 30 #include <strings.h> 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <errno.h> 34 #include <ctype.h> 35 #include <alloca.h> 36 #include <libgen.h> 37 #include <stddef.h> 38 39 #include <dt_impl.h> 40 #include <dt_program.h> 41 #include <dt_pid.h> 42 #include <dt_string.h> 43 44 typedef struct dt_pid_probe { 45 dtrace_hdl_t *dpp_dtp; 46 struct ps_prochandle *dpp_pr; 47 const char *dpp_mod; 48 char *dpp_func; 49 const char *dpp_name; 50 const char *dpp_obj; 51 uintptr_t dpp_pc; 52 size_t dpp_size; 53 Lmid_t dpp_lmid; 54 uint_t dpp_nmatches; 55 uint64_t dpp_stret[4]; 56 GElf_Sym dpp_last; 57 uint_t dpp_last_taken; 58 } dt_pid_probe_t; 59 60 static void 61 dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) 62 { 63 fasttrap_probe_spec_t *ftp; 64 uint64_t off; 65 char *end; 66 uint_t nmatches = 0; 67 ulong_t sz; 68 int glob, err; 69 int isdash = strcmp("-", func) == 0; 70 pid_t pid; 71 72 pid = Pstatus(pp->dpp_pr)->pr_pid; 73 74 dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid, pp->dpp_obj, 75 func, pp->dpp_name); 76 77 sz = sizeof (fasttrap_probe_spec_t) + (isdash ? 4 : 78 (symp->st_size - 1) * sizeof (ftp->ftps_offs[0])); 79 80 if (sz < 4000) { 81 ftp = alloca(sz); 82 sz = 0; 83 } else if ((ftp = malloc(sz)) == NULL) { 84 dt_dprintf("proc_per_sym: malloc(%lu) failed\n", sz); 85 return; 86 } 87 88 ftp->ftps_pid = pid; 89 (void) strncpy(ftp->ftps_func, func, sizeof (ftp->ftps_func)); 90 91 if (pp->dpp_lmid == 0) { 92 (void) strncpy(ftp->ftps_mod, pp->dpp_obj, 93 sizeof (ftp->ftps_mod)); 94 } else { 95 (void) snprintf(ftp->ftps_mod, sizeof (ftp->ftps_mod), 96 "LM%lx`%s", pp->dpp_lmid, pp->dpp_obj); 97 } 98 99 if (!isdash && gmatch("return", pp->dpp_name)) { 100 if (dt_pid_create_return_probe(pp->dpp_pr, pp->dpp_dtp, 101 ftp, symp, pp->dpp_stret) < 0) 102 goto create_err; 103 104 nmatches++; 105 } 106 107 if (!isdash && gmatch("entry", pp->dpp_name)) { 108 if (dt_pid_create_entry_probe(pp->dpp_pr, pp->dpp_dtp, 109 ftp, symp) < 0) 110 goto create_err; 111 112 nmatches++; 113 } 114 115 glob = strisglob(pp->dpp_name); 116 if (!glob && nmatches == 0) { 117 off = strtoull(pp->dpp_name, &end, 16); 118 if (*end != '\0') { 119 if (sz != 0) 120 free(ftp); 121 dt_proc_release(pp->dpp_dtp, pp->dpp_pr); 122 xyerror(D_PROC_NAME, "'%s' is an invalid probe name\n", 123 pp->dpp_name); 124 } 125 126 if (off >= symp->st_size) { 127 char buf[DTRACE_FUNCNAMELEN]; 128 /* 129 * We need to copy the function name to the stack 130 * because 'func' may be freed by virtue of calling 131 * dt_proc_release() on the libproc handle. 132 */ 133 (void) strncpy(buf, func, sizeof (buf)); 134 if (sz != 0) 135 free(ftp); 136 dt_proc_release(pp->dpp_dtp, pp->dpp_pr); 137 xyerror(D_PROC_OFF, "offset 0x%llx outside of " 138 "function '%s'\n", (u_longlong_t)off, buf); 139 } 140 141 err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp, 142 symp, off); 143 144 if (err == DT_PROC_ERR) 145 goto create_err; 146 if (err == DT_PROC_ALIGN) { 147 if (sz != 0) 148 free(ftp); 149 dt_proc_release(pp->dpp_dtp, pp->dpp_pr); 150 xyerror(D_PROC_ALIGN, "offset 0x%llx is not aligned " 151 "on an instruction\n", (u_longlong_t)off); 152 } 153 154 nmatches++; 155 156 } else if (glob && !isdash) { 157 if (dt_pid_create_glob_offset_probes(pp->dpp_pr, 158 pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) 159 goto create_err; 160 161 nmatches++; 162 } 163 164 pp->dpp_nmatches += nmatches; 165 166 if (sz != 0) 167 free(ftp); 168 return; 169 170 create_err: 171 if (sz != 0) 172 free(ftp); 173 174 dt_proc_release(pp->dpp_dtp, pp->dpp_pr); 175 xyerror(D_PROC_CREATEFAIL, "failed to create probe in process %d: %s\n", 176 (int)pid, dtrace_errmsg(pp->dpp_dtp, dtrace_errno(pp->dpp_dtp))); 177 } 178 179 static int 180 dt_pid_sym_filt(void *arg, const GElf_Sym *symp, const char *func) 181 { 182 dt_pid_probe_t *pp = arg; 183 184 if (symp->st_shndx == SHN_UNDEF) 185 return (0); 186 187 if (symp->st_size == 0) { 188 dt_dprintf("st_size of %s is zero\n", func); 189 return (0); 190 } 191 192 if (symp->st_value != pp->dpp_last.st_value || 193 symp->st_size != pp->dpp_last.st_size) { 194 /* 195 * Due to 4524008, _init and _fini may have a bloated st_size. 196 * While this bug has been fixed for a while, old binaries 197 * may exist that still exhibit this problem. As a result, we 198 * don't match _init and _fini though we allow users to 199 * specify them explicitly. 200 */ 201 if (strcmp(func, "_init") == 0 || strcmp(func, "_fini") == 0) 202 return (0); 203 204 if (gmatch(func, pp->dpp_func)) { 205 dt_pid_per_sym(pp, symp, func); 206 pp->dpp_last_taken = 1; 207 } 208 209 pp->dpp_last = *symp; 210 } 211 212 return (0); 213 } 214 215 static void 216 dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) 217 { 218 dt_pid_probe_t *pp = arg; 219 GElf_Sym sym; 220 221 if (obj == NULL) 222 return; 223 224 (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); 225 226 if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) 227 pp->dpp_obj = obj; 228 else 229 pp->dpp_obj++; 230 231 if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym, 232 NULL) == 0) 233 pp->dpp_stret[0] = sym.st_value; 234 else 235 pp->dpp_stret[0] = 0; 236 237 if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret2", &sym, 238 NULL) == 0) 239 pp->dpp_stret[1] = sym.st_value; 240 else 241 pp->dpp_stret[1] = 0; 242 243 if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret4", &sym, 244 NULL) == 0) 245 pp->dpp_stret[2] = sym.st_value; 246 else 247 pp->dpp_stret[2] = 0; 248 249 if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret8", &sym, 250 NULL) == 0) 251 pp->dpp_stret[3] = sym.st_value; 252 else 253 pp->dpp_stret[3] = 0; 254 255 dt_dprintf("%s stret %llx %llx %llx %llx\n", obj, 256 (u_longlong_t)pp->dpp_stret[0], (u_longlong_t)pp->dpp_stret[1], 257 (u_longlong_t)pp->dpp_stret[2], (u_longlong_t)pp->dpp_stret[3]); 258 259 /* 260 * If pp->dpp_func contains any globbing meta-characters, we need 261 * to iterate over the symbol table and compare each function name 262 * against the pattern. 263 */ 264 if (!strisglob(pp->dpp_func)) { 265 /* 266 * If we fail to lookup the symbol, try interpreting the 267 * function as the special "-" function that indicates that the 268 * probe name should be interpreted as a absolute virtual 269 * address. If that fails and we were matching a specific 270 * function in a specific module, report the error, otherwise 271 * just fail silently in the hopes that some other object will 272 * contain the desired symbol. 273 */ 274 if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, 275 pp->dpp_func, &sym, NULL) != 0) { 276 if (strcmp("-", pp->dpp_func) == 0) { 277 sym.st_name = 0; 278 sym.st_info = 279 GELF_ST_INFO(STB_LOCAL, STT_FUNC); 280 sym.st_other = 0; 281 sym.st_value = 0; 282 sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel == 283 PR_MODEL_ILP32 ? -1U : -1ULL; 284 285 } else if (!strisglob(pp->dpp_mod)) { 286 dt_proc_release(pp->dpp_dtp, pp->dpp_pr); 287 xyerror(D_PROC_FUNC, "failed to lookup '%s'\n", 288 pp->dpp_func); 289 } else { 290 return; 291 } 292 } 293 294 /* 295 * Only match defined functions of non-zero size. 296 */ 297 if (GELF_ST_TYPE(sym.st_info) != STT_FUNC || 298 sym.st_shndx == SHN_UNDEF || sym.st_size == 0) 299 return; 300 301 /* 302 * We don't instrument PLTs -- they're dynamically rewritten, 303 * and, so, inherently dicey to instrument. 304 */ 305 if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL) 306 return; 307 308 (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, 309 DTRACE_FUNCNAMELEN, &sym); 310 311 dt_pid_per_sym(pp, &sym, pp->dpp_func); 312 } else { 313 uint_t nmatches = pp->dpp_nmatches; 314 315 (void) Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, 316 BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp); 317 318 if (nmatches == pp->dpp_nmatches) { 319 /* 320 * If we didn't match anything in the PR_SYMTAB, try 321 * the PR_DYNSYM. 322 */ 323 (void) Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM, 324 BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp); 325 } 326 } 327 } 328 329 static int 330 dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) 331 { 332 dt_pid_probe_t *pp = arg; 333 334 if (gmatch(obj, pp->dpp_mod)) { 335 dt_pid_per_mod(pp, pmp, obj); 336 } else { 337 char name[DTRACE_MODNAMELEN]; 338 339 (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); 340 341 if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) 342 pp->dpp_obj = obj; 343 else 344 pp->dpp_obj++; 345 346 (void) snprintf(name, sizeof (name), "LM%lx`%s", 347 pp->dpp_lmid, obj); 348 349 if (gmatch(name, pp->dpp_mod)) 350 dt_pid_per_mod(pp, pmp, obj); 351 } 352 353 return (0); 354 } 355 356 static const prmap_t * 357 dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) 358 { 359 char m[MAXPATHLEN]; 360 Lmid_t lmid = PR_LMID_EVERY; 361 const char *obj; 362 const prmap_t *pmp; 363 364 /* 365 * Pick apart the link map from the library name. 366 */ 367 if (strchr(pdp->dtpd_mod, '`') != NULL) { 368 char *end; 369 370 if (strncmp(pdp->dtpd_mod, "LM", 2) != 0 || 371 !isdigit(pdp->dtpd_mod[2])) 372 return (NULL); 373 374 lmid = strtoul(&pdp->dtpd_mod[2], &end, 16); 375 376 obj = end + 1; 377 378 if (*end != '`' || strchr(obj, '`') != NULL) 379 return (NULL); 380 381 } else { 382 obj = pdp->dtpd_mod; 383 } 384 385 if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL) 386 return (NULL); 387 388 (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m)); 389 if ((obj = strrchr(m, '/')) == NULL) 390 obj = &m[0]; 391 else 392 obj++; 393 394 (void) Plmid(P, pmp->pr_vaddr, &lmid); 395 if (lmid == LM_ID_BASE) 396 (void) strcpy(pdp->dtpd_mod, obj); 397 else 398 (void) snprintf(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), 399 "LM%lx`%s", lmid, obj); 400 401 return (pmp); 402 } 403 404 405 static void 406 dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pid_t pid) 407 { 408 dt_pid_probe_t pp; 409 410 pp.dpp_pr = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0); 411 if (pp.dpp_pr == NULL) 412 longjmp(dtp->dt_pcb->pcb_jmpbuf, EDT_COMPILER); 413 414 /* 415 * We can only trace dynamically-linked executables (since we've 416 * hidden some magic in ld.so.1 as well as libc.so.1). 417 */ 418 if (Pname_to_map(pp.dpp_pr, PR_OBJ_LDSO) == NULL) { 419 dt_proc_release(dtp, pp.dpp_pr); 420 xyerror(D_PROC_DYN, "process %s is not a dynamically-linked " 421 "executable\n", &pdp->dtpd_provider[3]); 422 } 423 424 pp.dpp_dtp = dtp; 425 pp.dpp_mod = pdp->dtpd_mod[0] != '\0' ? pdp->dtpd_mod : "*"; 426 pp.dpp_func = pdp->dtpd_func[0] != '\0' ? pdp->dtpd_func : "*"; 427 pp.dpp_name = pdp->dtpd_name[0] != '\0' ? pdp->dtpd_name : "*"; 428 429 if (strcmp(pp.dpp_func, "-") == 0) { 430 const prmap_t *aout, *pmp; 431 432 if (pdp->dtpd_mod[0] == '\0') { 433 pp.dpp_mod = pdp->dtpd_mod; 434 (void) strcpy(pdp->dtpd_mod, "a.out"); 435 } else if (strisglob(pp.dpp_mod) || 436 (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL || 437 (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL || 438 aout->pr_vaddr != pmp->pr_vaddr) { 439 dt_proc_release(dtp, pp.dpp_pr); 440 xyerror(D_PROC_LIB, "only the a.out module is valid " 441 "with the '-' function\n"); 442 } 443 444 if (strisglob(pp.dpp_name)) { 445 dt_proc_release(dtp, pp.dpp_pr); 446 xyerror(D_PROC_NAME, "only individual addresses may " 447 "be specified with the '-' function\n"); 448 } 449 } 450 451 /* 452 * If pp.dpp_mod contains any globbing meta-characters, we need 453 * to iterate over each module and compare its name against the 454 * pattern. An empty module name is treated as '*'. 455 */ 456 if (strisglob(pp.dpp_mod)) { 457 (void) Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); 458 } else { 459 const prmap_t *pmp; 460 char *obj; 461 462 /* 463 * If can't find a matching module, don't sweat it -- either 464 * we'll fail the enabling because the probes don't exist or 465 * we'll wait for that module to come along. 466 */ 467 if ((pmp = dt_pid_fix_mod(pdp, pp.dpp_pr)) != NULL) { 468 if ((obj = strchr(pdp->dtpd_mod, '`')) == NULL) 469 obj = pdp->dtpd_mod; 470 else 471 obj++; 472 473 dt_pid_per_mod(&pp, pmp, obj); 474 } 475 } 476 477 dt_proc_release(dtp, pp.dpp_pr); 478 } 479 480 static int 481 dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) 482 { 483 struct ps_prochandle *P = data; 484 GElf_Sym sym; 485 prsyminfo_t sip; 486 int fd; 487 dof_helper_t dh; 488 GElf_Half e_type; 489 const char *mname; 490 const char *syms[] = { "___SUNW_dof", "__SUNW_dof" }; 491 int i; 492 493 /* 494 * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and 495 * __SUNW_dof is for actively-loaded DOF sections. We try to force 496 * in both types of DOF section since the process may not yet have 497 * run the code to instantiate these providers. 498 */ 499 for (i = 0; i < 2; i++) { 500 if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, 501 &sip) != 0) { 502 continue; 503 } 504 505 if ((mname = strrchr(oname, '/')) == NULL) 506 mname = oname; 507 else 508 mname++; 509 510 dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); 511 512 if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr + 513 offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) { 514 dt_dprintf("read of ELF header failed"); 515 continue; 516 } 517 518 dh.dofhp_dof = sym.st_value; 519 dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; 520 521 if (sip.prs_lmid == 0) { 522 (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod), 523 "%s", mname); 524 } else { 525 (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod), 526 "LM%lx`%s", sip.prs_lmid, mname); 527 } 528 529 if ((fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { 530 dt_dprintf("pr_open of helper device failed: %s\n", 531 strerror(errno)); 532 return (errno); 533 } 534 535 (void) pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)); 536 537 if (pr_close(P, fd) != 0) 538 return (errno); 539 } 540 541 return (0); 542 } 543 544 static int 545 dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dt_proc_t *dpr) 546 { 547 struct ps_prochandle *P = dpr->dpr_proc; 548 int err; 549 550 assert(DT_MUTEX_HELD(&dpr->dpr_lock)); 551 552 (void) Pupdate_maps(P); 553 err = Pobject_iter(P, dt_pid_usdt_mapping, P); 554 555 /* 556 * Put the module name in its canonical form. 557 */ 558 (void) dt_pid_fix_mod(pdp, P); 559 560 return (err); 561 } 562 563 static pid_t 564 dt_pid_get_pid(dtrace_probedesc_t *pdp, int *errp) 565 { 566 pid_t pid; 567 char *c, *last = NULL, *end; 568 569 for (c = &pdp->dtpd_provider[0]; *c != '\0'; c++) { 570 if (!isdigit(*c)) 571 last = c; 572 } 573 574 if (last == NULL || (*(++last) == '\0')) { 575 if (errp != NULL) { 576 *errp = D_PROC_BADPROV; 577 return (-1); 578 } 579 xyerror(D_PROC_BADPROV, "%s is not a valid provider\n", 580 pdp->dtpd_provider); 581 } 582 583 errno = 0; 584 pid = strtol(last, &end, 10); 585 586 if (errno != 0 || end == last || end[0] != '\0' || pid <= 0) { 587 if (errp != NULL) { 588 *errp = D_PROC_BADPID; 589 return (-1); 590 } 591 xyerror(D_PROC_BADPID, "%s does not contain a valid pid\n", 592 pdp->dtpd_provider); 593 } 594 595 if (errp != NULL) 596 *errp = 0; 597 598 return (pid); 599 } 600 601 void 602 dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp) 603 { 604 pid_t pid = dt_pid_get_pid(pdp, NULL); 605 char provname[DTRACE_PROVNAMELEN]; 606 struct ps_prochandle *P; 607 dt_proc_t *dpr; 608 int err = 0; 609 610 if (dtp->dt_ftfd == -1) { 611 if (dtp->dt_fterr == ENOENT) { 612 xyerror(D_PROC_NODEV, "pid provider is not " 613 "installed on this system\n"); 614 } else { 615 xyerror(D_PROC_NODEV, "pid provider is not " 616 "available: %s\n", strerror(dtp->dt_fterr)); 617 } 618 } 619 620 (void) snprintf(provname, sizeof (provname), "pid%d", (int)pid); 621 622 if (strcmp(provname, pdp->dtpd_provider) == 0) { 623 dt_pid_create_pid_probes(pdp, dtp, pid); 624 } else { 625 if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) 626 longjmp(dtp->dt_pcb->pcb_jmpbuf, EDT_COMPILER); 627 628 dpr = dt_proc_lookup(dtp, P, 0); 629 assert(dpr != NULL); 630 631 (void) pthread_mutex_lock(&dpr->dpr_lock); 632 633 if (!dpr->dpr_usdt) { 634 err = dt_pid_create_usdt_probes(pdp, dpr); 635 dpr->dpr_usdt = B_TRUE; 636 } 637 638 (void) pthread_mutex_unlock(&dpr->dpr_lock); 639 640 dt_proc_release(dtp, P); 641 642 if (err != 0) 643 xyerror(D_PROC_USDT, "failed to instantiate probes " 644 "for PID %d: %s", (int)pid, strerror(err)); 645 } 646 } 647 648 void 649 dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) 650 { 651 dtrace_prog_t *pgp; 652 dt_stmt_t *stp; 653 char provname[DTRACE_PROVNAMELEN]; 654 dtrace_probedesc_t *pdp, pd; 655 pid_t pid; 656 int err; 657 int found = B_FALSE; 658 659 for (pgp = dt_list_next(&dtp->dt_programs); pgp != NULL; 660 pgp = dt_list_next(pgp)) { 661 662 for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; 663 stp = dt_list_next(stp)) { 664 665 pdp = &stp->ds_desc->dtsd_ecbdesc->dted_probe; 666 pid = dt_pid_get_pid(pdp, &err); 667 if (err != 0 || pid != dpr->dpr_pid) 668 continue; 669 670 found = B_TRUE; 671 672 pd = *pdp; 673 674 (void) snprintf(provname, sizeof (provname), "pid%d", 675 (int)pid); 676 677 if (strcmp(provname, pdp->dtpd_provider) == 0) 678 dt_pid_create_pid_probes(&pd, dtp, pid); 679 else 680 (void) dt_pid_create_usdt_probes(&pd, dpr); 681 } 682 } 683 684 if (found) { 685 /* 686 * Give DTrace a shot to the ribs to get it to check 687 * out the newly created probes. 688 */ 689 (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL); 690 } 691 } 692