PERFORCE change 133097 for review
John Birrell
jb at FreeBSD.org
Fri Jan 11 21:07:13 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=133097
Change 133097 by jb at jb_freebsd1 on 2008/01/12 05:06:53
WIP.
Enable use of our libproc to create a process, ptrace it, wait
for it to stop, start it and check that it ends.
More work required to attach to an existing process and to enable
breakpoints, stop and start via DTrace actions, etc.
Affected files ...
.. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_proc.c#7 edit
Differences ...
==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_proc.c#7 (text) ====
@@ -117,27 +117,36 @@
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)
{
@@ -206,7 +215,6 @@
#endif
}
-#ifdef DOODAD
static void
dt_proc_notify(dtrace_hdl_t *dtp, dt_proc_hash_t *dph, dt_proc_t *dpr,
const char *msg)
@@ -274,6 +282,7 @@
dt_proc_stop(dpr, DT_PROC_STOP_MAIN);
}
+#ifdef DOODAD
static void
dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname)
{
@@ -450,6 +459,7 @@
(void) pthread_mutex_lock(&dpr->dpr_lock);
}
+#endif
typedef struct dt_proc_control_data {
dtrace_hdl_t *dpcd_hdl; /* DTrace handle */
@@ -476,11 +486,13 @@
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;
/*
@@ -498,6 +510,7 @@
*/
(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 */
@@ -543,7 +556,14 @@
dt_dprintf("pid %d: failed to set running: %s\n",
(int)dpr->dpr_pid, strerror(errno));
}
+#else
+ dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
+ 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);
/*
@@ -556,20 +576,34 @@
* 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:
+printf("Process has stopped!\n");
+#ifdef DOODAD
psp = &Pstatus(P)->pr_lwp;
dt_dprintf("pid %d: proc stopped showing %d/%d\n",
@@ -612,11 +646,15 @@
else if (psp->pr_why == PR_SYSEXIT &&
IS_SYS_EXEC(psp->pr_what))
dt_proc_attach(dpr, B_TRUE);
+#endif
break;
case PS_LOST:
+printf("Process has been lost!\n");
+#if defined(sun)
if (Preopen(P) == 0)
goto pwait_locked;
+#endif
dt_dprintf("pid %d: proc lost: %s\n",
pid, strerror(errno));
@@ -626,16 +664,19 @@
break;
case PS_UNDEAD:
+printf("Process is undead!\n");
dt_dprintf("pid %d: proc died\n", pid);
dpr->dpr_quit = B_TRUE;
notify = B_TRUE;
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);
}
@@ -675,21 +716,26 @@
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);
return (NULL);
}
-#endif
dt_proc_t *
dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)
{
-printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
-#ifdef DOODAD
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) {
@@ -706,9 +752,6 @@
*dpp = dpr->dpr_hash; /* remove from pid hash chain */
return (dpr);
-#else
-return NULL;
-#endif
}
static void
@@ -806,7 +849,6 @@
#endif
}
-#ifdef DOODAD
static int
dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
{
@@ -823,7 +865,11 @@
(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;
@@ -851,14 +897,21 @@
* 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 "
@@ -867,6 +920,7 @@
(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 */
@@ -882,13 +936,10 @@
return (err);
}
-#endif
struct ps_prochandle *
dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
{
-printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
-#ifdef DOODAD
dt_proc_hash_t *dph = dtp->dt_procs;
dt_proc_t *dpr;
int err;
@@ -899,6 +950,7 @@
(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)));
@@ -909,8 +961,19 @@
(void) Punsetflags(dpr->dpr_proc, PR_RLC);
(void) Psetflags(dpr->dpr_proc, PR_KLC);
+#else
+ 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)];
@@ -921,9 +984,6 @@
dpr->dpr_refs++;
return (dpr->dpr_proc);
-#else
-return NULL;
-#endif
}
struct ps_prochandle *
@@ -1028,8 +1088,6 @@
void
dt_proc_release(dtrace_hdl_t *dtp, struct ps_prochandle *P)
{
-printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
-#ifdef DOODAD
dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
dt_proc_hash_t *dph = dtp->dt_procs;
@@ -1039,7 +1097,6 @@
if (--dpr->dpr_refs == 0 &&
(!dpr->dpr_cacheable || dph->dph_lrucnt > dph->dph_lrulim))
dt_proc_destroy(dtp, P);
-#endif
}
void
@@ -1103,18 +1160,17 @@
struct ps_prochandle *
dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
{
-printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
-#ifdef DOODAD
dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
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);
-#else
-return NULL;
-#endif
}
struct ps_prochandle *
More information about the p4-projects
mailing list