summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>2008-04-26 04:51:45 +0000
committerjb <jb@FreeBSD.org>2008-04-26 04:51:45 +0000
commit118f2174646e3d709f9f14bc93bee8cc59a15c12 (patch)
tree679ef9d9b97bcd53563e15f258a95bcca07eb35f /cddl
parent729d998abb4de35b849eeb88c356c993761fdfb7 (diff)
downloadFreeBSD-src-118f2174646e3d709f9f14bc93bee8cc59a15c12.zip
FreeBSD-src-118f2174646e3d709f9f14bc93bee8cc59a15c12.tar.gz
* Use FreeBSD's process library instead of the Solaris one.
* There are a few placeholders in here for which there isn't libproc support code yet. This is relevent to userland tracing. This set of commits is designed to get kernel tracing up and running, with the userland stuff to follow later.
Diffstat (limited to 'cddl')
-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 419f13b..b8662bf 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);
}
OpenPOWER on IntegriCloud