diff options
author | jb <jb@FreeBSD.org> | 2008-04-26 04:51:45 +0000 |
---|---|---|
committer | jb <jb@FreeBSD.org> | 2008-04-26 04:51:45 +0000 |
commit | 118f2174646e3d709f9f14bc93bee8cc59a15c12 (patch) | |
tree | 679ef9d9b97bcd53563e15f258a95bcca07eb35f /cddl | |
parent | 729d998abb4de35b849eeb88c356c993761fdfb7 (diff) | |
download | FreeBSD-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.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 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); } |