aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
diff options
context:
space:
mode:
authorJohn Birrell <jb@FreeBSD.org>2008-04-26 04:51:45 +0000
committerJohn Birrell <jb@FreeBSD.org>2008-04-26 04:51:45 +0000
commitbbda5851ce01e8040dc26b3ef8f3c451a924ceea (patch)
tree679ef9d9b97bcd53563e15f258a95bcca07eb35f /cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
parentd46d190310e8851648631dbfa3435c6d6077eb38 (diff)
downloadsrc-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.c123
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);
}