diff options
Diffstat (limited to 'usr/src/lib/libdtrace/common/dt_pid.c')
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_pid.c | 409 |
1 files changed, 231 insertions, 178 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_pid.c b/usr/src/lib/libdtrace/common/dt_pid.c index b91cf6ef56..35f51ec1c3 100644 --- a/usr/src/lib/libdtrace/common/dt_pid.c +++ b/usr/src/lib/libdtrace/common/dt_pid.c @@ -19,8 +19,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -42,19 +43,21 @@ #include <dt_string.h> typedef struct dt_pid_probe { - dtrace_hdl_t *dpp_dtp; - struct ps_prochandle *dpp_pr; - const char *dpp_mod; - char *dpp_func; - const char *dpp_name; - const char *dpp_obj; - uintptr_t dpp_pc; - size_t dpp_size; - Lmid_t dpp_lmid; - uint_t dpp_nmatches; - uint64_t dpp_stret[4]; - GElf_Sym dpp_last; - uint_t dpp_last_taken; + dtrace_hdl_t *dpp_dtp; + dt_pcb_t *dpp_pcb; + dt_proc_t *dpp_dpr; + struct ps_prochandle *dpp_pr; + const char *dpp_mod; + char *dpp_func; + const char *dpp_name; + const char *dpp_obj; + uintptr_t dpp_pc; + size_t dpp_size; + Lmid_t dpp_lmid; + uint_t dpp_nmatches; + uint64_t dpp_stret[4]; + GElf_Sym dpp_last; + uint_t dpp_last_taken; } dt_pid_probe_t; /* @@ -70,19 +73,39 @@ dt_pid_objname(char *buf, size_t len, Lmid_t lmid, const char *obj) (void) snprintf(buf, len, "LM%lx`%s", lmid, obj); } -static void -dt_pid_error(dtrace_hdl_t *dtp, dt_errtag_t tag, const char *fmt, ...) +static int +dt_pid_error(dtrace_hdl_t *dtp, dt_pcb_t *pcb, dt_proc_t *dpr, + fasttrap_probe_spec_t *ftp, dt_errtag_t tag, const char *fmt, ...) { va_list ap; + int len; + + if (ftp != NULL) + dt_free(dtp, ftp); va_start(ap, fmt); - dt_set_errmsg(dtp, dt_errtag(tag), NULL, NULL, 0, fmt, ap); + if (pcb == NULL) { + assert(dpr != NULL); + len = vsnprintf(dpr->dpr_errmsg, sizeof (dpr->dpr_errmsg), + fmt, ap); + assert(len >= 2); + if (dpr->dpr_errmsg[len - 2] == '\n') + dpr->dpr_errmsg[len - 2] = '\0'; + } else { + dt_set_errmsg(dtp, dt_errtag(tag), pcb->pcb_region, + pcb->pcb_filetag, pcb->pcb_fileptr ? yylineno : 0, fmt, ap); + } va_end(ap); + + return (1); } -static void +static int dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) { + dtrace_hdl_t *dtp = pp->dpp_dtp; + dt_pcb_t *pcb = pp->dpp_pcb; + dt_proc_t *dpr = pp->dpp_dpr; fasttrap_probe_spec_t *ftp; uint64_t off; char *end; @@ -100,12 +123,9 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) sz = sizeof (fasttrap_probe_spec_t) + (isdash ? 4 : (symp->st_size - 1) * sizeof (ftp->ftps_offs[0])); - if (sz < 4000) { - ftp = alloca(sz); - sz = 0; - } else if ((ftp = malloc(sz)) == NULL) { - dt_dprintf("proc_per_sym: malloc(%lu) failed\n", sz); - return; + if ((ftp = dt_alloc(dtp, sz)) == NULL) { + dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz); + return (1); /* errno is set for us */ } ftp->ftps_pid = pid; @@ -115,17 +135,24 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) pp->dpp_obj); if (!isdash && gmatch("return", pp->dpp_name)) { - if (dt_pid_create_return_probe(pp->dpp_pr, pp->dpp_dtp, - ftp, symp, pp->dpp_stret) < 0) - goto create_err; + if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp, + pp->dpp_stret) < 0) { + return (dt_pid_error(dtp, pcb, dpr, ftp, + D_PROC_CREATEFAIL, "failed to create return probe " + "for '%s': %s", func, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + } nmatches++; } if (!isdash && gmatch("entry", pp->dpp_name)) { - if (dt_pid_create_entry_probe(pp->dpp_pr, pp->dpp_dtp, - ftp, symp) < 0) - goto create_err; + if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) { + return (dt_pid_error(dtp, pcb, dpr, ftp, + D_PROC_CREATEFAIL, "failed to create entry probe " + "for '%s': %s", func, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + } nmatches++; } @@ -134,65 +161,51 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) if (!glob && nmatches == 0) { off = strtoull(pp->dpp_name, &end, 16); if (*end != '\0') { - if (sz != 0) - free(ftp); - dt_proc_release(pp->dpp_dtp, pp->dpp_pr); - xyerror(D_PROC_NAME, "'%s' is an invalid probe name\n", - pp->dpp_name); + return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_NAME, + "'%s' is an invalid probe name", pp->dpp_name)); } if (off >= symp->st_size) { - dt_pid_error(pp->dpp_dtp, D_PROC_OFF, "offset " - "0x%llx outside of function '%s'\n", - (u_longlong_t)off, func); - goto out; + return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_OFF, + "offset 0x%llx outside of function '%s'", + (u_longlong_t)off, func)); } err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp, symp, off); - if (err == DT_PROC_ERR) - goto create_err; + if (err == DT_PROC_ERR) { + return (dt_pid_error(dtp, pcb, dpr, ftp, + D_PROC_CREATEFAIL, "failed to create probe at " + "'%s+0x%llx': %s", func, (u_longlong_t)off, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + } + if (err == DT_PROC_ALIGN) { -#ifdef __sparc - if (sz != 0) - free(ftp); - dt_proc_release(pp->dpp_dtp, pp->dpp_pr); - xyerror(D_PROC_ALIGN, "offset 0x%llx is not properly " - "aligned\n", (u_longlong_t)off); -#else - dt_pid_error(pp->dpp_dtp, D_PROC_ALIGN, "offset " - "0x%llx is not aligned on an instruction\n", - (u_longlong_t)off); - goto out; -#endif + return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_ALIGN, + "offset 0x%llx is not aligned on an instruction", + (u_longlong_t)off)); } nmatches++; } else if (glob && !isdash) { if (dt_pid_create_glob_offset_probes(pp->dpp_pr, - pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) - goto create_err; + pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) { + return (dt_pid_error(dtp, pcb, dpr, ftp, + D_PROC_CREATEFAIL, + "failed to create offset probes in '%s': %s", func, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + } nmatches++; } pp->dpp_nmatches += nmatches; -out: - if (sz != 0) - free(ftp); - return; + dt_free(dtp, ftp); -create_err: - if (sz != 0) - free(ftp); - - dt_proc_release(pp->dpp_dtp, pp->dpp_pr); - dt_pid_error(pp->dpp_dtp, D_PROC_CREATEFAIL, "failed to create " - "probe in process %d: %s", (int)pid, - dtrace_errmsg(pp->dpp_dtp, dtrace_errno(pp->dpp_dtp))); + return (0); } static int @@ -208,7 +221,8 @@ dt_pid_sym_filt(void *arg, const GElf_Sym *symp, const char *func) return (0); } - if (symp->st_value != pp->dpp_last.st_value || + if (pp->dpp_last_taken == 0 || + symp->st_value != pp->dpp_last.st_value || symp->st_size != pp->dpp_last.st_size) { /* * Due to 4524008, _init and _fini may have a bloated st_size. @@ -220,25 +234,26 @@ dt_pid_sym_filt(void *arg, const GElf_Sym *symp, const char *func) if (strcmp(func, "_init") == 0 || strcmp(func, "_fini") == 0) return (0); - if (gmatch(func, pp->dpp_func)) { - dt_pid_per_sym(pp, symp, func); - pp->dpp_last_taken = 1; + if ((pp->dpp_last_taken = gmatch(func, pp->dpp_func)) != 0) { + pp->dpp_last = *symp; + return (dt_pid_per_sym(pp, symp, func)); } - - pp->dpp_last = *symp; } return (0); } -static void +static int dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) { dt_pid_probe_t *pp = arg; + dtrace_hdl_t *dtp = pp->dpp_dtp; + dt_pcb_t *pcb = pp->dpp_pcb; + dt_proc_t *dpr = pp->dpp_dpr; GElf_Sym sym; if (obj == NULL) - return; + return (0); (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); @@ -302,12 +317,12 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) PR_MODEL_ILP32 ? -1U : -1ULL; } else if (!strisglob(pp->dpp_mod)) { - dt_proc_release(pp->dpp_dtp, pp->dpp_pr); - xyerror(D_PROC_FUNC, "failed to lookup '%s' " - "in module '%s'\n", pp->dpp_func, - pp->dpp_mod); + return (dt_pid_error(dtp, pcb, dpr, NULL, + D_PROC_FUNC, + "failed to lookup '%s' in module '%s'", + pp->dpp_func, pp->dpp_mod)); } else { - return; + return (0); } } @@ -316,58 +331,60 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) */ if (GELF_ST_TYPE(sym.st_info) != STT_FUNC || sym.st_shndx == SHN_UNDEF || sym.st_size == 0) - return; + return (0); /* * We don't instrument PLTs -- they're dynamically rewritten, * and, so, inherently dicey to instrument. */ if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL) - return; + return (0); (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, DTRACE_FUNCNAMELEN, &sym); - dt_pid_per_sym(pp, &sym, pp->dpp_func); + return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { uint_t nmatches = pp->dpp_nmatches; - (void) Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, - BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp); + if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, + BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) + return (1); if (nmatches == pp->dpp_nmatches) { /* * If we didn't match anything in the PR_SYMTAB, try * the PR_DYNSYM. */ - (void) Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM, - BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp); + if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM, + BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) + return (1); } } + + return (0); } static int dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) { + char name[DTRACE_MODNAMELEN]; dt_pid_probe_t *pp = arg; - if (gmatch(obj, pp->dpp_mod)) { - dt_pid_per_mod(pp, pmp, obj); - } else { - char name[DTRACE_MODNAMELEN]; + if (gmatch(obj, pp->dpp_mod)) + return (dt_pid_per_mod(pp, pmp, obj)); - (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); + (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); - if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) - pp->dpp_obj = obj; - else - pp->dpp_obj++; + if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) + pp->dpp_obj = obj; + else + pp->dpp_obj++; - dt_pid_objname(name, sizeof (name), pp->dpp_lmid, obj); + dt_pid_objname(name, sizeof (name), pp->dpp_lmid, obj); - if (gmatch(name, pp->dpp_mod)) - dt_pid_per_mod(pp, pmp, obj); - } + if (gmatch(name, pp->dpp_mod)) + return (dt_pid_per_mod(pp, pmp, obj)); return (0); } @@ -417,29 +434,38 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) } -static void -dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pid_t pid) +static int +dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, + dt_pcb_t *pcb, dt_proc_t *dpr) { dt_pid_probe_t pp; + int ret = 0; - pp.dpp_pr = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0); - if (pp.dpp_pr == NULL) - longjmp(dtp->dt_pcb->pcb_jmpbuf, EDT_COMPILER); + /* + * Disable breakpoints so they don't interfere with our disassembly. + */ + dt_proc_bpdisable(dpr); + + pp.dpp_dtp = dtp; + pp.dpp_dpr = dpr; + pp.dpp_pr = dpr->dpr_proc; + pp.dpp_pcb = pcb; /* * We can only trace dynamically-linked executables (since we've * hidden some magic in ld.so.1 as well as libc.so.1). */ if (Pname_to_map(pp.dpp_pr, PR_OBJ_LDSO) == NULL) { - dt_proc_release(dtp, pp.dpp_pr); - xyerror(D_PROC_DYN, "process %s is not a dynamically-linked " - "executable\n", &pdp->dtpd_provider[3]); + dt_proc_bpenable(dpr); + return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_DYN, + "process %s is not a dynamically-linked executable", + &pdp->dtpd_provider[3])); } - pp.dpp_dtp = dtp; pp.dpp_mod = pdp->dtpd_mod[0] != '\0' ? pdp->dtpd_mod : "*"; pp.dpp_func = pdp->dtpd_func[0] != '\0' ? pdp->dtpd_func : "*"; pp.dpp_name = pdp->dtpd_name[0] != '\0' ? pdp->dtpd_name : "*"; + pp.dpp_last_taken = 0; if (strcmp(pp.dpp_func, "-") == 0) { const prmap_t *aout, *pmp; @@ -451,15 +477,17 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pid_t pid) (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL || (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL || aout->pr_vaddr != pmp->pr_vaddr) { - dt_proc_release(dtp, pp.dpp_pr); - xyerror(D_PROC_LIB, "only the a.out module is valid " - "with the '-' function\n"); + dt_proc_bpenable(dpr); + return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB, + "only the a.out module is valid with the " + "'-' function")); } if (strisglob(pp.dpp_name)) { - dt_proc_release(dtp, pp.dpp_pr); - xyerror(D_PROC_NAME, "only individual addresses may " - "be specified with the '-' function\n"); + dt_proc_bpenable(dpr); + return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_NAME, + "only individual addresses may be specified " + "with the '-' function")); } } @@ -469,13 +497,13 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pid_t pid) * pattern. An empty module name is treated as '*'. */ if (strisglob(pp.dpp_mod)) { - (void) Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); + ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); } else { const prmap_t *pmp; char *obj; /* - * If can't find a matching module, don't sweat it -- either + * If we can't find a matching module, don't sweat it -- either * we'll fail the enabling because the probes don't exist or * we'll wait for that module to come along. */ @@ -485,11 +513,13 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pid_t pid) else obj++; - dt_pid_per_mod(&pp, pmp, obj); + ret = dt_pid_per_mod(&pp, pmp, obj); } } - dt_proc_release(dtp, pp.dpp_pr); + dt_proc_bpenable(dpr); + + return (ret); } static int @@ -498,12 +528,11 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) struct ps_prochandle *P = data; GElf_Sym sym; prsyminfo_t sip; - int fd; dof_helper_t dh; GElf_Half e_type; const char *mname; const char *syms[] = { "___SUNW_dof", "__SUNW_dof" }; - int i; + int i, fd = -1; /* * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and @@ -536,42 +565,51 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), sip.prs_lmid, mname); - if ((fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { + if (fd == -1 && + (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", strerror(errno)); - return (errno); + return (-1); /* errno is set for us */ } - (void) pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)); - - if (pr_close(P, fd) != 0) - return (errno); + if (pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0) + dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod); } + if (fd != -1) + (void) pr_close(P, fd); + return (0); } static int -dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dt_proc_t *dpr) +dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, + dt_pcb_t *pcb, dt_proc_t *dpr) { struct ps_prochandle *P = dpr->dpr_proc; - int err; + int ret = 0; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); (void) Pupdate_maps(P); - err = Pobject_iter(P, dt_pid_usdt_mapping, P); + if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) { + ret = -1; + (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT, + "failed to instantiate probes for pid %d: %s", + (int)Pstatus(P)->pr_pid, strerror(errno)); + } /* * Put the module name in its canonical form. */ (void) dt_pid_fix_mod(pdp, P); - return (err); + return (ret); } static pid_t -dt_pid_get_pid(dtrace_probedesc_t *pdp, int *errp) +dt_pid_get_pid(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb, + dt_proc_t *dpr) { pid_t pid; char *c, *last = NULL, *end; @@ -582,89 +620,100 @@ dt_pid_get_pid(dtrace_probedesc_t *pdp, int *errp) } if (last == NULL || (*(++last) == '\0')) { - if (errp != NULL) { - *errp = D_PROC_BADPROV; - return (-1); - } - xyerror(D_PROC_BADPROV, "%s is not a valid provider\n", - pdp->dtpd_provider); + (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPROV, + "'%s' is not a valid provider", pdp->dtpd_provider); + return (-1); } errno = 0; pid = strtol(last, &end, 10); if (errno != 0 || end == last || end[0] != '\0' || pid <= 0) { - if (errp != NULL) { - *errp = D_PROC_BADPID; - return (-1); - } - xyerror(D_PROC_BADPID, "%s does not contain a valid pid\n", - pdp->dtpd_provider); + (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPID, + "'%s' does not contain a valid pid", pdp->dtpd_provider); + return (-1); } - if (errp != NULL) - *errp = 0; - return (pid); } -void -dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp) +int +dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb) { - pid_t pid = dt_pid_get_pid(pdp, NULL); char provname[DTRACE_PROVNAMELEN]; struct ps_prochandle *P; dt_proc_t *dpr; - int err = 0; + pid_t pid; + int err; + + assert(pcb != NULL); + + if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1) + return (-1); if (dtp->dt_ftfd == -1) { if (dtp->dt_fterr == ENOENT) { - xyerror(D_PROC_NODEV, "pid provider is not " - "installed on this system\n"); + (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV, + "pid provider is not installed on this system"); } else { - xyerror(D_PROC_NODEV, "pid provider is not " - "available: %s\n", strerror(dtp->dt_fterr)); + (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV, + "pid provider is not available: %s", + strerror(dtp->dt_fterr)); } + + return (-1); } (void) snprintf(provname, sizeof (provname), "pid%d", (int)pid); if (strcmp(provname, pdp->dtpd_provider) == 0) { - dt_pid_create_pid_probes(pdp, dtp, pid); - } else { - if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) - longjmp(dtp->dt_pcb->pcb_jmpbuf, EDT_COMPILER); + if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, + 0)) == NULL) { + (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB, + "failed to grab process %d", (int)pid); + return (-1); + } dpr = dt_proc_lookup(dtp, P, 0); assert(dpr != NULL); + (void) pthread_mutex_lock(&dpr->dpr_lock); + + err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr); + (void) pthread_mutex_unlock(&dpr->dpr_lock); + dt_proc_release(dtp, P); + + } else { + if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) { + (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB, + "failed to grab process %d", (int)pid); + return (-1); + } + + dpr = dt_proc_lookup(dtp, P, 0); + assert(dpr != NULL); (void) pthread_mutex_lock(&dpr->dpr_lock); if (!dpr->dpr_usdt) { - err = dt_pid_create_usdt_probes(pdp, dpr); + err = dt_pid_create_usdt_probes(pdp, dtp, pcb, dpr); dpr->dpr_usdt = B_TRUE; } (void) pthread_mutex_unlock(&dpr->dpr_lock); - dt_proc_release(dtp, P); - - if (err != 0) - dt_pid_error(dtp, D_PROC_USDT, "failed to instantiate " - "probes for PID %d: %s", (int)pid, strerror(err)); } + + return (err ? -1 : 0); } -void +int dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) { dtrace_prog_t *pgp; dt_stmt_t *stp; - char provname[DTRACE_PROVNAMELEN]; dtrace_probedesc_t *pdp, pd; pid_t pid; - int err; - int found = B_FALSE; + int ret = 0, found = B_FALSE; for (pgp = dt_list_next(&dtp->dt_programs); pgp != NULL; pgp = dt_list_next(pgp)) { @@ -673,21 +722,23 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) stp = dt_list_next(stp)) { pdp = &stp->ds_desc->dtsd_ecbdesc->dted_probe; - pid = dt_pid_get_pid(pdp, &err); - if (err != 0 || pid != dpr->dpr_pid) + pid = dt_pid_get_pid(pdp, dtp, NULL, dpr); + if (pid != dpr->dpr_pid) continue; found = B_TRUE; pd = *pdp; - (void) snprintf(provname, sizeof (provname), "pid%d", - (int)pid); - - if (strcmp(provname, pdp->dtpd_provider) == 0) - dt_pid_create_pid_probes(&pd, dtp, pid); - else - (void) dt_pid_create_usdt_probes(&pd, dpr); + if (strncmp(pdp->dtpd_provider, "pid", 3) == 0) { + if (dt_pid_create_pid_probes(&pd, dtp, NULL, + dpr) != 0) + ret = 1; + } else { + if (dt_pid_create_usdt_probes(&pd, dtp, NULL, + dpr) != 0) + ret = 1; + } } } @@ -698,4 +749,6 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) */ (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL); } + + return (ret); } |