const char * mdb_strerror(int err) { static char buf[256]; const char *str; if (err >= EMDB_BASE && (err - EMDB_BASE) < _mdb_nerr) str = _mdb_errlist[err - EMDB_BASE]; else str = strerror(err); switch (err) { case EMDB_PARTIAL: (void) mdb_iob_snprintf(buf, sizeof (buf), str, errno_rbytes, errno_nbytes); str = buf; break; #ifndef _KMDB case EMDB_RTLD_DB: if (rd_errstr(errno_rtld_db) != NULL) str = rd_errstr(errno_rtld_db); break; #endif case EMDB_CTF: if (ctf_errmsg(errno_libctf) != NULL) str = ctf_errmsg(errno_libctf); break; } return (str ? str : "unknown error"); }
static void dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname) { rd_notify_t rdn; rd_err_e err; if ((err = rd_event_addr(dpr->dpr_rtld, event, &rdn)) != RD_OK) { dt_dprintf("pid %d: failed to get event address for %s: %s\n", (int)dpr->dpr_pid, evname, rd_errstr(err)); return; } if (rdn.type != RD_NOTIFY_BPT) { dt_dprintf("pid %d: event %s has unexpected type %d\n", (int)dpr->dpr_pid, evname, rdn.type); return; } (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr, (dt_bkpt_f *)dt_proc_rdevent, (void *)evname); }
static void dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname) { rd_event_msg_t rdm; rd_err_e err; if ((err = rd_event_getmsg(dpr->dpr_rtld, &rdm)) != RD_OK) { dt_dprintf("pid %d: failed to get %s event message: %s\n", (int)dpr->dpr_pid, evname, rd_errstr(err)); return; } dt_dprintf("pid %d: rtld event %s type=%d state %d\n", (int)dpr->dpr_pid, evname, rdm.type, rdm.u.state); switch (rdm.type) { case RD_DLACTIVITY: if (rdm.u.state != RD_CONSISTENT) break; Pupdate_syms(dpr->dpr_proc); if (dt_pid_create_probes_module(dtp, dpr) != 0) dt_proc_notify(dtp, dtp->dt_procs, dpr, dpr->dpr_errmsg); break; case RD_PREINIT: Pupdate_syms(dpr->dpr_proc); dt_proc_stop(dpr, DT_PROC_STOP_PREINIT); break; case RD_POSTINIT: Pupdate_syms(dpr->dpr_proc); dt_proc_stop(dpr, DT_PROC_STOP_POSTINIT); break; } // Take note of symbol owners (i.e. modules) already processed. */ if (!(dpr->dpr_stop & ~DT_PROC_STOP_IDLE)) Pcheckpoint_syms(dpr->dpr_proc); }
/* * Common code for enabling events associated with the run-time linker after * attaching to a process or after a victim process completes an exec(2). */ static void dt_proc_attach(dt_proc_t *dpr, int exec) { const pstatus_t *psp = Pstatus(dpr->dpr_proc); rd_err_e err; GElf_Sym sym; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); if (exec) { if (psp->pr_lwp.pr_errno != 0) return; /* exec failed: nothing needs to be done */ dt_proc_bpdestroy(dpr, B_FALSE); Preset_maps(dpr->dpr_proc); } if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL && (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) { dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT"); dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT"); dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY"); } else { dt_dprintf("pid %d: failed to enable rtld events: %s\n", (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) : "rtld_db agent initialization failed"); } Pupdate_maps(dpr->dpr_proc); if (Pxlookup_by_name(dpr->dpr_proc, LM_ID_BASE, "a.out", "main", &sym, NULL) == 0) { (void) dt_proc_bpcreate(dpr, (uintptr_t)sym.st_value, (dt_bkpt_f *)dt_proc_bpmain, "a.out`main"); } else { dt_dprintf("pid %d: failed to find a.out`main: %s\n", (int)dpr->dpr_pid, strerror(errno)); } }