diff options
author | John Birrell <jb@FreeBSD.org> | 2008-04-26 04:51:45 +0000 |
---|---|---|
committer | John Birrell <jb@FreeBSD.org> | 2008-04-26 04:51:45 +0000 |
commit | bbda5851ce01e8040dc26b3ef8f3c451a924ceea (patch) | |
tree | 679ef9d9b97bcd53563e15f258a95bcca07eb35f /cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c | |
parent | d46d190310e8851648631dbfa3435c6d6077eb38 (diff) | |
download | src-bbda5851ce01e8040dc26b3ef8f3c451a924ceea.tar.gz src-bbda5851ce01e8040dc26b3ef8f3c451a924ceea.zip |
Notes
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c | 123 |
1 files changed, 122 insertions, 1 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c index 419f13b8474c..b8662bf67f34 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c @@ -79,7 +79,9 @@ */ #include <sys/wait.h> +#if defined(sun) #include <sys/lwp.h> +#endif #include <strings.h> #include <signal.h> #include <assert.h> @@ -93,6 +95,7 @@ #define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_fork1 || \ w == SYS_forkall || w == SYS_forksys) +#ifdef DOODAD static dt_bkpt_t * dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) { @@ -114,27 +117,36 @@ dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) return (dbp); } +#endif static void dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts) { +#if defined(sun) int state = Pstate(dpr->dpr_proc); +#else + int state = proc_state(dpr->dpr_proc); +#endif dt_bkpt_t *dbp, *nbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) { +printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); +#ifdef DOODAD if (delbkpts && dbp->dbp_active && state != PS_LOST && state != PS_UNDEAD) { (void) Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr); } +#endif nbp = dt_list_next(dbp); dt_list_delete(&dpr->dpr_bps, dbp); dt_free(dpr->dpr_hdl, dbp); } } +#ifdef DOODAD static void dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) { @@ -161,6 +173,7 @@ dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) dbp->dbp_func(dtp, dpr, dbp->dbp_data); (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr); } +#endif static void dt_proc_bpenable(dt_proc_t *dpr) @@ -171,9 +184,12 @@ dt_proc_bpenable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { +printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); +#ifdef DOODAD if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc, dbp->dbp_addr, &dbp->dbp_instr) == 0) dbp->dbp_active = B_TRUE; +#endif } dt_dprintf("breakpoints enabled\n"); @@ -188,9 +204,12 @@ dt_proc_bpdisable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { +printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); +#ifdef DOODAD if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr) == 0) dbp->dbp_active = B_FALSE; +#endif } dt_dprintf("breakpoints disabled\n"); @@ -263,6 +282,7 @@ dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname) dt_proc_stop(dpr, DT_PROC_STOP_MAIN); } +#if defined(sun) static void dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname) { @@ -439,6 +459,7 @@ dt_proc_waitrun(dt_proc_t *dpr) (void) pthread_mutex_lock(&dpr->dpr_lock); } +#endif typedef struct dt_proc_control_data { dtrace_hdl_t *dpcd_hdl; /* DTrace handle */ @@ -465,11 +486,13 @@ dt_proc_control(void *arg) dt_proc_t *dpr = datap->dpcd_proc; dt_proc_hash_t *dph = dpr->dpr_hdl->dt_procs; struct ps_prochandle *P = dpr->dpr_proc; + int pid = dpr->dpr_pid; +#if defined(sun) int pfd = Pctlfd(P); - int pid = dpr->dpr_pid; const long wstop = PCWSTOP; +#endif int notify = B_FALSE; /* @@ -487,6 +510,7 @@ dt_proc_control(void *arg) */ (void) pthread_mutex_lock(&dpr->dpr_lock); +#if defined(sun) (void) Punsetflags(P, PR_ASYNC); /* require synchronous mode */ (void) Psetflags(P, PR_BPTADJ); /* always adjust eip on x86 */ (void) Punsetflags(P, PR_FORK); /* do not inherit on fork */ @@ -532,6 +556,20 @@ dt_proc_control(void *arg) dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); } +#else + /* + * If PR_KLC is set, we created the process; otherwise we grabbed it. + * Check for an appropriate stop request and wait for dt_proc_continue. + */ + if (proc_getflags(P) & PR_KLC) + dt_proc_stop(dpr, DT_PROC_STOP_CREATE); + else + dt_proc_stop(dpr, DT_PROC_STOP_GRAB); + + if (proc_continue(P) != 0) + dt_dprintf("pid %d: failed to set running: %s\n", + (int)dpr->dpr_pid, strerror(errno)); +#endif (void) pthread_mutex_unlock(&dpr->dpr_lock); @@ -545,20 +583,33 @@ dt_proc_control(void *arg) * Pwait() (which will return immediately) and do our processing. */ while (!dpr->dpr_quit) { +#if defined(sun) const lwpstatus_t *psp; if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR) continue; /* check dpr_quit and continue waiting */ +#else + /* Wait for the process to report status. */ + proc_wait(P); +#endif (void) pthread_mutex_lock(&dpr->dpr_lock); + +#if defined(sun) pwait_locked: if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) { (void) pthread_mutex_unlock(&dpr->dpr_lock); continue; /* check dpr_quit and continue waiting */ } +#endif +#if defined(sun) switch (Pstate(P)) { +#else + switch (proc_state(P)) { +#endif case PS_STOP: +#ifdef DOODAD psp = &Pstatus(P)->pr_lwp; dt_dprintf("pid %d: proc stopped showing %d/%d\n", @@ -601,11 +652,14 @@ pwait_locked: else if (psp->pr_why == PR_SYSEXIT && IS_SYS_EXEC(psp->pr_what)) dt_proc_attach(dpr, B_TRUE); +#endif break; case PS_LOST: +#if defined(sun) if (Preopen(P) == 0) goto pwait_locked; +#endif dt_dprintf("pid %d: proc lost: %s\n", pid, strerror(errno)); @@ -621,10 +675,12 @@ pwait_locked: break; } +#if defined(sun) if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) { dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); } +#endif (void) pthread_mutex_unlock(&dpr->dpr_lock); } @@ -664,7 +720,11 @@ dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...) va_end(ap); if (dpr->dpr_proc != NULL) +#if defined(sun) Prelease(dpr->dpr_proc, 0); +#else + proc_detach(dpr->dpr_proc); +#endif dt_free(dtp, dpr); (void) dt_set_errno(dtp, EDT_COMPILER); @@ -675,7 +735,11 @@ dt_proc_t * dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove) { dt_proc_hash_t *dph = dtp->dt_procs; +#if defined(sun) pid_t pid = Pstatus(P)->pr_pid; +#else + pid_t pid = proc_getpid(P); +#endif dt_proc_t *dpr, **dpp = &dph->dph_hash[pid & (dph->dph_hashlen - 1)]; for (dpr = *dpp; dpr != NULL; dpr = dpr->dpr_hash) { @@ -709,9 +773,17 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) * an external debugger and we were waiting in dt_proc_waitrun(). * Leave the process in this condition using PRELEASE_HANG. */ +#if defined(sun) if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) { +#else + if (!(proc_getflags(dpr->dpr_proc) & (PR_KLC | PR_RLC))) { +#endif dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid); +#if defined(sun) rflag = PRELEASE_HANG; +#else + rflag = 0 /* XXX */; +#endif } else { dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid); rflag = 0; /* apply kill or run-on-last-close */ @@ -734,7 +806,11 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) */ (void) pthread_mutex_lock(&dpr->dpr_lock); dpr->dpr_quit = B_TRUE; +#if defined(sun) (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL); +#else + (void) pthread_kill(dpr->dpr_tid, SIGUSR1); +#endif /* * If the process is currently idling in dt_proc_stop(), re- @@ -782,7 +858,11 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) } dt_list_delete(&dph->dph_lrulist, dpr); +#if defined(sun) Prelease(dpr->dpr_proc, rflag); +#else + proc_detach(dpr->dpr_proc); +#endif dt_free(dtp, dpr); } @@ -802,7 +882,11 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) (void) sigfillset(&nset); (void) sigdelset(&nset, SIGABRT); /* unblocked for assert() */ +#if defined(sun) (void) sigdelset(&nset, SIGCANCEL); /* see dt_proc_destroy() */ +#else + (void) sigdelset(&nset, SIGUSR1); /* see dt_proc_destroy() */ +#endif data.dpcd_hdl = dtp; data.dpcd_proc = dpr; @@ -830,14 +914,21 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) * small amount of useful information to help figure it out. */ if (dpr->dpr_done) { +#if defined(sun) const psinfo_t *prp = Ppsinfo(dpr->dpr_proc); int stat = prp ? prp->pr_wstat : 0; +#endif int pid = dpr->dpr_pid; +#if defined(sun) if (Pstate(dpr->dpr_proc) == PS_LOST) { +#else + if (proc_state(dpr->dpr_proc) == PS_LOST) { +#endif (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exec'd " "set-id or unobservable program\n", pid); +#if defined(sun) } else if (WIFSIGNALED(stat)) { (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process died " @@ -846,6 +937,7 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exited " "with status %d\n", pid, WEXITSTATUS(stat)); +#endif } err = ESRCH; /* cause grab() or create() to fail */ @@ -875,6 +967,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv) (void) pthread_mutex_init(&dpr->dpr_lock, NULL); (void) pthread_cond_init(&dpr->dpr_cv, NULL); +#if defined(sun) if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) { return (dt_proc_error(dtp, dpr, "failed to execute %s: %s\n", file, Pcreate_error(err))); @@ -885,8 +978,21 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv) (void) Punsetflags(dpr->dpr_proc, PR_RLC); (void) Psetflags(dpr->dpr_proc, PR_KLC); +#else + (void) proc_clearflags(dpr->dpr_proc, PR_RLC); + (void) proc_setflags(dpr->dpr_proc, PR_KLC); + if ((err = proc_create(file, argv, &dpr->dpr_proc)) != 0) + return (dt_proc_error(dtp, dpr, + "failed to execute %s: %s\n", file, strerror(err))); + dpr->dpr_hdl = dtp; + dpr->dpr_pid = proc_getpid(dpr->dpr_proc); +#endif +#if defined(sun) if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0) +#else + if (dt_proc_create_thread(dtp, dpr, DT_PROC_STOP_IDLE) != 0) +#endif return (NULL); /* dt_proc_error() has been called for us */ dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)]; @@ -942,16 +1048,27 @@ dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor) (void) pthread_mutex_init(&dpr->dpr_lock, NULL); (void) pthread_cond_init(&dpr->dpr_cv, NULL); +#if defined(sun) if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) { return (dt_proc_error(dtp, dpr, "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err))); } +#else + if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) + return (dt_proc_error(dtp, dpr, + "failed to grab pid %d: %s\n", (int) pid, strerror(err))); +#endif dpr->dpr_hdl = dtp; dpr->dpr_pid = pid; +#if defined(sun) (void) Punsetflags(dpr->dpr_proc, PR_KLC); (void) Psetflags(dpr->dpr_proc, PR_RLC); +#else + (void) proc_clearflags(dpr->dpr_proc, PR_KLC); + (void) proc_setflags(dpr->dpr_proc, PR_RLC); +#endif /* * If we are attempting to grab the process without a monitor @@ -1072,7 +1189,11 @@ dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv) struct ps_prochandle *P = dt_proc_create(dtp, file, argv); if (P != NULL && idp != NULL && idp->di_id == 0) +#if defined(sun) idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */ +#else + idp->di_id = proc_getpid(P); /* $target = created pid */ +#endif return (P); } |