Deleted Added
full compact
dt_proc.c (210775) dt_proc.c (211554)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 75 unchanged lines hidden (view full) ---

84#include <signal.h>
85#include <assert.h>
86#include <errno.h>
87
88#include <dt_proc.h>
89#include <dt_pid.h>
90#include <dt_impl.h>
91
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 75 unchanged lines hidden (view full) ---

84#include <signal.h>
85#include <assert.h>
86#include <errno.h>
87
88#include <dt_proc.h>
89#include <dt_pid.h>
90#include <dt_impl.h>
91
92#if !defined(sun)
93#include <sys/syscall.h>
94#include <libproc_compat.h>
95#define SYS_forksys SYS_fork
96#endif
97
92#define IS_SYS_EXEC(w) (w == SYS_execve)
93#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
94
98#define IS_SYS_EXEC(w) (w == SYS_execve)
99#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
100
95#ifdef DOODAD
96static dt_bkpt_t *
97dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data)
98{
99 struct ps_prochandle *P = dpr->dpr_proc;
100 dt_bkpt_t *dbp;
101
102 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
103

--- 5 unchanged lines hidden (view full) ---

109 if (Psetbkpt(P, dbp->dbp_addr, &dbp->dbp_instr) == 0)
110 dbp->dbp_active = B_TRUE;
111
112 dt_list_append(&dpr->dpr_bps, dbp);
113 }
114
115 return (dbp);
116}
101static dt_bkpt_t *
102dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data)
103{
104 struct ps_prochandle *P = dpr->dpr_proc;
105 dt_bkpt_t *dbp;
106
107 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
108

--- 5 unchanged lines hidden (view full) ---

114 if (Psetbkpt(P, dbp->dbp_addr, &dbp->dbp_instr) == 0)
115 dbp->dbp_active = B_TRUE;
116
117 dt_list_append(&dpr->dpr_bps, dbp);
118 }
119
120 return (dbp);
121}
117#endif
118
119static void
120dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
121{
122
123static void
124dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
125{
122#if defined(sun)
123 int state = Pstate(dpr->dpr_proc);
126 int state = Pstate(dpr->dpr_proc);
124#else
125 int state = proc_state(dpr->dpr_proc);
126#endif
127 dt_bkpt_t *dbp, *nbp;
128
129 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
130
131 for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) {
127 dt_bkpt_t *dbp, *nbp;
128
129 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
130
131 for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) {
132printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
133#ifdef DOODAD
134 if (delbkpts && dbp->dbp_active &&
135 state != PS_LOST && state != PS_UNDEAD) {
136 (void) Pdelbkpt(dpr->dpr_proc,
137 dbp->dbp_addr, dbp->dbp_instr);
138 }
132 if (delbkpts && dbp->dbp_active &&
133 state != PS_LOST && state != PS_UNDEAD) {
134 (void) Pdelbkpt(dpr->dpr_proc,
135 dbp->dbp_addr, dbp->dbp_instr);
136 }
139#endif
140 nbp = dt_list_next(dbp);
141 dt_list_delete(&dpr->dpr_bps, dbp);
142 dt_free(dpr->dpr_hdl, dbp);
143 }
144}
145
137 nbp = dt_list_next(dbp);
138 dt_list_delete(&dpr->dpr_bps, dbp);
139 dt_free(dpr->dpr_hdl, dbp);
140 }
141}
142
146#ifdef DOODAD
147static void
148dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
149{
143static void
144dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
145{
146#if defined(sun)
150 const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
147 const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
148#else
149 unsigned long pc;
150#endif
151 dt_bkpt_t *dbp;
152
153 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
154
151 dt_bkpt_t *dbp;
152
153 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
154
155#if !defined(sun)
156 proc_regget(dpr->dpr_proc, REG_PC, &pc);
157 proc_bkptregadj(&pc);
158#endif
159
155 for (dbp = dt_list_next(&dpr->dpr_bps);
156 dbp != NULL; dbp = dt_list_next(dbp)) {
160 for (dbp = dt_list_next(&dpr->dpr_bps);
161 dbp != NULL; dbp = dt_list_next(dbp)) {
162#if defined(sun)
157 if (psp->pr_reg[R_PC] == dbp->dbp_addr)
158 break;
163 if (psp->pr_reg[R_PC] == dbp->dbp_addr)
164 break;
165#else
166 if (pc == dbp->dbp_addr)
167 break;
168#endif
159 }
160
161 if (dbp == NULL) {
162 dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
169 }
170
171 if (dbp == NULL) {
172 dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
173#if defined(sun)
163 (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
174 (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
175#else
176 (int)dpr->dpr_pid, pc);
177#endif
164 return;
165 }
166
167 dt_dprintf("pid %d: hit breakpoint at %lx (%lu)\n",
168 (int)dpr->dpr_pid, (ulong_t)dbp->dbp_addr, ++dbp->dbp_hits);
169
170 dbp->dbp_func(dtp, dpr, dbp->dbp_data);
171 (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr);
172}
178 return;
179 }
180
181 dt_dprintf("pid %d: hit breakpoint at %lx (%lu)\n",
182 (int)dpr->dpr_pid, (ulong_t)dbp->dbp_addr, ++dbp->dbp_hits);
183
184 dbp->dbp_func(dtp, dpr, dbp->dbp_data);
185 (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr);
186}
173#endif
174
175static void
176dt_proc_bpenable(dt_proc_t *dpr)
177{
178 dt_bkpt_t *dbp;
179
180 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
181
182 for (dbp = dt_list_next(&dpr->dpr_bps);
183 dbp != NULL; dbp = dt_list_next(dbp)) {
187
188static void
189dt_proc_bpenable(dt_proc_t *dpr)
190{
191 dt_bkpt_t *dbp;
192
193 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
194
195 for (dbp = dt_list_next(&dpr->dpr_bps);
196 dbp != NULL; dbp = dt_list_next(dbp)) {
184printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
185#ifdef DOODAD
186 if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc,
187 dbp->dbp_addr, &dbp->dbp_instr) == 0)
188 dbp->dbp_active = B_TRUE;
197 if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc,
198 dbp->dbp_addr, &dbp->dbp_instr) == 0)
199 dbp->dbp_active = B_TRUE;
189#endif
190 }
191
192 dt_dprintf("breakpoints enabled\n");
193}
194
195static void
196dt_proc_bpdisable(dt_proc_t *dpr)
197{
198 dt_bkpt_t *dbp;
199
200 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
201
202 for (dbp = dt_list_next(&dpr->dpr_bps);
203 dbp != NULL; dbp = dt_list_next(dbp)) {
200 }
201
202 dt_dprintf("breakpoints enabled\n");
203}
204
205static void
206dt_proc_bpdisable(dt_proc_t *dpr)
207{
208 dt_bkpt_t *dbp;
209
210 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
211
212 for (dbp = dt_list_next(&dpr->dpr_bps);
213 dbp != NULL; dbp = dt_list_next(dbp)) {
204printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
205#ifdef DOODAD
206 if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc,
207 dbp->dbp_addr, dbp->dbp_instr) == 0)
208 dbp->dbp_active = B_FALSE;
214 if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc,
215 dbp->dbp_addr, dbp->dbp_instr) == 0)
216 dbp->dbp_active = B_FALSE;
209#endif
210 }
211
212 dt_dprintf("breakpoints disabled\n");
213}
214
215static void
216dt_proc_notify(dtrace_hdl_t *dtp, dt_proc_hash_t *dph, dt_proc_t *dpr,
217 const char *msg)

--- 56 unchanged lines hidden (view full) ---

274/*ARGSUSED*/
275static void
276dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname)
277{
278 dt_dprintf("pid %d: breakpoint at %s()\n", (int)dpr->dpr_pid, fname);
279 dt_proc_stop(dpr, DT_PROC_STOP_MAIN);
280}
281
217 }
218
219 dt_dprintf("breakpoints disabled\n");
220}
221
222static void
223dt_proc_notify(dtrace_hdl_t *dtp, dt_proc_hash_t *dph, dt_proc_t *dpr,
224 const char *msg)

--- 56 unchanged lines hidden (view full) ---

281/*ARGSUSED*/
282static void
283dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname)
284{
285 dt_dprintf("pid %d: breakpoint at %s()\n", (int)dpr->dpr_pid, fname);
286 dt_proc_stop(dpr, DT_PROC_STOP_MAIN);
287}
288
282#if defined(sun)
283static void
284dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname)
285{
286 rd_event_msg_t rdm;
287 rd_err_e err;
288
289 if ((err = rd_event_getmsg(dpr->dpr_rtld, &rdm)) != RD_OK) {
290 dt_dprintf("pid %d: failed to get %s event message: %s\n",

--- 40 unchanged lines hidden (view full) ---

331
332 if (rdn.type != RD_NOTIFY_BPT) {
333 dt_dprintf("pid %d: event %s has unexpected type %d\n",
334 (int)dpr->dpr_pid, evname, rdn.type);
335 return;
336 }
337
338 (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr,
289static void
290dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname)
291{
292 rd_event_msg_t rdm;
293 rd_err_e err;
294
295 if ((err = rd_event_getmsg(dpr->dpr_rtld, &rdm)) != RD_OK) {
296 dt_dprintf("pid %d: failed to get %s event message: %s\n",

--- 40 unchanged lines hidden (view full) ---

337
338 if (rdn.type != RD_NOTIFY_BPT) {
339 dt_dprintf("pid %d: event %s has unexpected type %d\n",
340 (int)dpr->dpr_pid, evname, rdn.type);
341 return;
342 }
343
344 (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr,
345#if defined(sun)
339 (dt_bkpt_f *)dt_proc_rdevent, (void *)evname);
346 (dt_bkpt_f *)dt_proc_rdevent, (void *)evname);
347#else
348 /* XXX ugly */
349 (dt_bkpt_f *)dt_proc_rdevent, __DECONST(void *, evname));
350#endif
340}
341
342/*
343 * Common code for enabling events associated with the run-time linker after
344 * attaching to a process or after a victim process completes an exec(2).
345 */
346static void
347dt_proc_attach(dt_proc_t *dpr, int exec)
348{
351}
352
353/*
354 * Common code for enabling events associated with the run-time linker after
355 * attaching to a process or after a victim process completes an exec(2).
356 */
357static void
358dt_proc_attach(dt_proc_t *dpr, int exec)
359{
360#if defined(sun)
349 const pstatus_t *psp = Pstatus(dpr->dpr_proc);
361 const pstatus_t *psp = Pstatus(dpr->dpr_proc);
362#endif
350 rd_err_e err;
351 GElf_Sym sym;
352
353 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
354
355 if (exec) {
363 rd_err_e err;
364 GElf_Sym sym;
365
366 assert(DT_MUTEX_HELD(&dpr->dpr_lock));
367
368 if (exec) {
369#if defined(sun)
356 if (psp->pr_lwp.pr_errno != 0)
357 return; /* exec failed: nothing needs to be done */
370 if (psp->pr_lwp.pr_errno != 0)
371 return; /* exec failed: nothing needs to be done */
372#endif
358
359 dt_proc_bpdestroy(dpr, B_FALSE);
373
374 dt_proc_bpdestroy(dpr, B_FALSE);
375#if defined(sun)
360 Preset_maps(dpr->dpr_proc);
376 Preset_maps(dpr->dpr_proc);
377#endif
361 }
378 }
362
363 if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL &&
364 (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) {
379 if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL &&
380 (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) {
381#if defined(sun)
365 dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT");
382 dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT");
383#endif
366 dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT");
384 dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT");
385#if defined(sun)
367 dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY");
386 dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY");
387#endif
368 } else {
369 dt_dprintf("pid %d: failed to enable rtld events: %s\n",
370 (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) :
371 "rtld_db agent initialization failed");
372 }
373
374 Pupdate_maps(dpr->dpr_proc);
375

--- 25 unchanged lines hidden (view full) ---

401 * changes, the representative LWP ID changes, or the stop timestamp advances.
402 * dt_proc_control() will then rediscover the new state and continue as usual.
403 * When the process is still stopped in the same exact state, we sleep for a
404 * brief interval before waiting again so as not to spin consuming CPU cycles.
405 */
406static void
407dt_proc_waitrun(dt_proc_t *dpr)
408{
388 } else {
389 dt_dprintf("pid %d: failed to enable rtld events: %s\n",
390 (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) :
391 "rtld_db agent initialization failed");
392 }
393
394 Pupdate_maps(dpr->dpr_proc);
395

--- 25 unchanged lines hidden (view full) ---

421 * changes, the representative LWP ID changes, or the stop timestamp advances.
422 * dt_proc_control() will then rediscover the new state and continue as usual.
423 * When the process is still stopped in the same exact state, we sleep for a
424 * brief interval before waiting again so as not to spin consuming CPU cycles.
425 */
426static void
427dt_proc_waitrun(dt_proc_t *dpr)
428{
429printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
430#ifdef DOODAD
409 struct ps_prochandle *P = dpr->dpr_proc;
410 const lwpstatus_t *psp = &Pstatus(P)->pr_lwp;
411
412 int krflag = psp->pr_flags & (PR_KLC | PR_RLC);
413 timestruc_t tstamp = psp->pr_tstamp;
414 lwpid_t lwpid = psp->pr_lwpid;
415
416 const long wstop = PCWSTOP;

--- 33 unchanged lines hidden (view full) ---

450 return;
451 }
452
453 (void) pthread_mutex_unlock(&dpr->dpr_lock);
454 (void) poll(NULL, 0, MILLISEC / 2);
455 }
456
457 (void) pthread_mutex_lock(&dpr->dpr_lock);
431 struct ps_prochandle *P = dpr->dpr_proc;
432 const lwpstatus_t *psp = &Pstatus(P)->pr_lwp;
433
434 int krflag = psp->pr_flags & (PR_KLC | PR_RLC);
435 timestruc_t tstamp = psp->pr_tstamp;
436 lwpid_t lwpid = psp->pr_lwpid;
437
438 const long wstop = PCWSTOP;

--- 33 unchanged lines hidden (view full) ---

472 return;
473 }
474
475 (void) pthread_mutex_unlock(&dpr->dpr_lock);
476 (void) poll(NULL, 0, MILLISEC / 2);
477 }
478
479 (void) pthread_mutex_lock(&dpr->dpr_lock);
458}
459#endif
480#endif
481}
460
461typedef struct dt_proc_control_data {
462 dtrace_hdl_t *dpcd_hdl; /* DTrace handle */
463 dt_proc_t *dpcd_proc; /* proccess to control */
464} dt_proc_control_data_t;
465
466/*
467 * Main loop for all victim process control threads. We initialize all the

--- 60 unchanged lines hidden (view full) ---

528 * does not inherit any other tracing behaviors or a control thread.
529 */
530 (void) Psysentry(P, SYS_vfork, B_TRUE);
531 (void) Psysexit(P, SYS_vfork, B_TRUE);
532 (void) Psysentry(P, SYS_forksys, B_TRUE);
533 (void) Psysexit(P, SYS_forksys, B_TRUE);
534
535 Psync(P); /* enable all /proc changes */
482
483typedef struct dt_proc_control_data {
484 dtrace_hdl_t *dpcd_hdl; /* DTrace handle */
485 dt_proc_t *dpcd_proc; /* proccess to control */
486} dt_proc_control_data_t;
487
488/*
489 * Main loop for all victim process control threads. We initialize all the

--- 60 unchanged lines hidden (view full) ---

550 * does not inherit any other tracing behaviors or a control thread.
551 */
552 (void) Psysentry(P, SYS_vfork, B_TRUE);
553 (void) Psysexit(P, SYS_vfork, B_TRUE);
554 (void) Psysentry(P, SYS_forksys, B_TRUE);
555 (void) Psysexit(P, SYS_forksys, B_TRUE);
556
557 Psync(P); /* enable all /proc changes */
558#endif
536 dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */
537
538 /*
539 * If PR_KLC is set, we created the process; otherwise we grabbed it.
540 * Check for an appropriate stop request and wait for dt_proc_continue.
541 */
559 dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */
560
561 /*
562 * If PR_KLC is set, we created the process; otherwise we grabbed it.
563 * Check for an appropriate stop request and wait for dt_proc_continue.
564 */
565#if defined(sun)
542 if (Pstatus(P)->pr_flags & PR_KLC)
566 if (Pstatus(P)->pr_flags & PR_KLC)
567#else
568 if (proc_getflags(P) & PR_KLC)
569#endif
543 dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
544 else
545 dt_proc_stop(dpr, DT_PROC_STOP_GRAB);
546
547 if (Psetrun(P, 0, 0) == -1) {
548 dt_dprintf("pid %d: failed to set running: %s\n",
549 (int)dpr->dpr_pid, strerror(errno));
550 }
570 dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
571 else
572 dt_proc_stop(dpr, DT_PROC_STOP_GRAB);
573
574 if (Psetrun(P, 0, 0) == -1) {
575 dt_dprintf("pid %d: failed to set running: %s\n",
576 (int)dpr->dpr_pid, strerror(errno));
577 }
551#else
552 /*
553 * If PR_KLC is set, we created the process; otherwise we grabbed it.
554 * Check for an appropriate stop request and wait for dt_proc_continue.
555 */
556 if (proc_getflags(P) & PR_KLC)
557 dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
558 else
559 dt_proc_stop(dpr, DT_PROC_STOP_GRAB);
560
578
561 if (proc_continue(P) != 0)
562 dt_dprintf("pid %d: failed to set running: %s\n",
563 (int)dpr->dpr_pid, strerror(errno));
564#endif
565
566 (void) pthread_mutex_unlock(&dpr->dpr_lock);
567
568 /*
569 * Wait for the process corresponding to this control thread to stop,
570 * process the event, and then set it running again. We want to sleep
571 * with dpr_lock *unheld* so that other parts of libdtrace can use the
572 * ps_prochandle in the meantime (e.g. ustack()). To do this, we write
573 * a PCWSTOP directive directly to the underlying /proc/<pid>/ctl file.
574 * Once the process stops, we wake up, grab dpr_lock, and then call
575 * Pwait() (which will return immediately) and do our processing.
576 */
577 while (!dpr->dpr_quit) {
579 (void) pthread_mutex_unlock(&dpr->dpr_lock);
580
581 /*
582 * Wait for the process corresponding to this control thread to stop,
583 * process the event, and then set it running again. We want to sleep
584 * with dpr_lock *unheld* so that other parts of libdtrace can use the
585 * ps_prochandle in the meantime (e.g. ustack()). To do this, we write
586 * a PCWSTOP directive directly to the underlying /proc/<pid>/ctl file.
587 * Once the process stops, we wake up, grab dpr_lock, and then call
588 * Pwait() (which will return immediately) and do our processing.
589 */
590 while (!dpr->dpr_quit) {
578#if defined(sun)
579 const lwpstatus_t *psp;
580
591 const lwpstatus_t *psp;
592
593#if defined(sun)
581 if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
582 continue; /* check dpr_quit and continue waiting */
583#else
584 /* Wait for the process to report status. */
585 proc_wstatus(P);
594 if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
595 continue; /* check dpr_quit and continue waiting */
596#else
597 /* Wait for the process to report status. */
598 proc_wstatus(P);
599 if (errno == EINTR)
600 continue; /* check dpr_quit and continue waiting */
586#endif
587
588 (void) pthread_mutex_lock(&dpr->dpr_lock);
589
590#if defined(sun)
591pwait_locked:
592 if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) {
593 (void) pthread_mutex_unlock(&dpr->dpr_lock);
594 continue; /* check dpr_quit and continue waiting */
595 }
596#endif
597
601#endif
602
603 (void) pthread_mutex_lock(&dpr->dpr_lock);
604
605#if defined(sun)
606pwait_locked:
607 if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) {
608 (void) pthread_mutex_unlock(&dpr->dpr_lock);
609 continue; /* check dpr_quit and continue waiting */
610 }
611#endif
612
598#if defined(sun)
599 switch (Pstate(P)) {
613 switch (Pstate(P)) {
600#else
601 switch (proc_state(P)) {
602#endif
603 case PS_STOP:
614 case PS_STOP:
604#ifdef DOODAD
615#if defined(sun)
605 psp = &Pstatus(P)->pr_lwp;
616 psp = &Pstatus(P)->pr_lwp;
617#else
618 psp = proc_getlwpstatus(P);
619#endif
606
607 dt_dprintf("pid %d: proc stopped showing %d/%d\n",
608 pid, psp->pr_why, psp->pr_what);
609
610 /*
611 * If the process stops showing PR_REQUESTED, then the
612 * DTrace stop() action was applied to it or another
613 * debugging utility (e.g. pstop(1)) asked it to stop.

--- 25 unchanged lines hidden (view full) ---

639 IS_SYS_FORK(psp->pr_what))
640 dt_proc_bpdisable(dpr);
641 else if (psp->pr_why == PR_SYSEXIT &&
642 IS_SYS_FORK(psp->pr_what))
643 dt_proc_bpenable(dpr);
644 else if (psp->pr_why == PR_SYSEXIT &&
645 IS_SYS_EXEC(psp->pr_what))
646 dt_proc_attach(dpr, B_TRUE);
620
621 dt_dprintf("pid %d: proc stopped showing %d/%d\n",
622 pid, psp->pr_why, psp->pr_what);
623
624 /*
625 * If the process stops showing PR_REQUESTED, then the
626 * DTrace stop() action was applied to it or another
627 * debugging utility (e.g. pstop(1)) asked it to stop.

--- 25 unchanged lines hidden (view full) ---

653 IS_SYS_FORK(psp->pr_what))
654 dt_proc_bpdisable(dpr);
655 else if (psp->pr_why == PR_SYSEXIT &&
656 IS_SYS_FORK(psp->pr_what))
657 dt_proc_bpenable(dpr);
658 else if (psp->pr_why == PR_SYSEXIT &&
659 IS_SYS_EXEC(psp->pr_what))
660 dt_proc_attach(dpr, B_TRUE);
647#endif
648 break;
649
650 case PS_LOST:
651#if defined(sun)
652 if (Preopen(P) == 0)
653 goto pwait_locked;
654#endif
655

--- 6 unchanged lines hidden (view full) ---

662
663 case PS_UNDEAD:
664 dt_dprintf("pid %d: proc died\n", pid);
665 dpr->dpr_quit = B_TRUE;
666 notify = B_TRUE;
667 break;
668 }
669
661 break;
662
663 case PS_LOST:
664#if defined(sun)
665 if (Preopen(P) == 0)
666 goto pwait_locked;
667#endif
668

--- 6 unchanged lines hidden (view full) ---

675
676 case PS_UNDEAD:
677 dt_dprintf("pid %d: proc died\n", pid);
678 dpr->dpr_quit = B_TRUE;
679 notify = B_TRUE;
680 break;
681 }
682
670#if defined(sun)
671 if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) {
672 dt_dprintf("pid %d: failed to set running: %s\n",
673 (int)dpr->dpr_pid, strerror(errno));
674 }
683 if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) {
684 dt_dprintf("pid %d: failed to set running: %s\n",
685 (int)dpr->dpr_pid, strerror(errno));
686 }
675#endif
676
677 (void) pthread_mutex_unlock(&dpr->dpr_lock);
678 }
679
680 /*
681 * If the control thread detected PS_UNDEAD or PS_LOST, then enqueue
682 * the dt_proc_t structure on the dt_proc_hash_t notification list.
683 */

--- 23 unchanged lines hidden (view full) ---

707{
708 va_list ap;
709
710 va_start(ap, format);
711 dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
712 va_end(ap);
713
714 if (dpr->dpr_proc != NULL)
687
688 (void) pthread_mutex_unlock(&dpr->dpr_lock);
689 }
690
691 /*
692 * If the control thread detected PS_UNDEAD or PS_LOST, then enqueue
693 * the dt_proc_t structure on the dt_proc_hash_t notification list.
694 */

--- 23 unchanged lines hidden (view full) ---

718{
719 va_list ap;
720
721 va_start(ap, format);
722 dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
723 va_end(ap);
724
725 if (dpr->dpr_proc != NULL)
715#if defined(sun)
716 Prelease(dpr->dpr_proc, 0);
726 Prelease(dpr->dpr_proc, 0);
717#else
718 proc_detach(dpr->dpr_proc, 0);
719#endif
720
721 dt_free(dtp, dpr);
722 (void) dt_set_errno(dtp, EDT_COMPILER);
723 return (NULL);
724}
725
726dt_proc_t *
727dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)

--- 71 unchanged lines hidden (view full) ---

799 * to do the job. This is all built on evil knowledge of
800 * the details of the cancellation mechanism in libc.
801 */
802 (void) pthread_mutex_lock(&dpr->dpr_lock);
803 dpr->dpr_quit = B_TRUE;
804#if defined(sun)
805 (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
806#else
727
728 dt_free(dtp, dpr);
729 (void) dt_set_errno(dtp, EDT_COMPILER);
730 return (NULL);
731}
732
733dt_proc_t *
734dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)

--- 71 unchanged lines hidden (view full) ---

806 * to do the job. This is all built on evil knowledge of
807 * the details of the cancellation mechanism in libc.
808 */
809 (void) pthread_mutex_lock(&dpr->dpr_lock);
810 dpr->dpr_quit = B_TRUE;
811#if defined(sun)
812 (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
813#else
807 (void) pthread_kill(dpr->dpr_tid, SIGUSR1);
814 pthread_kill(dpr->dpr_tid, SIGUSR1);
808#endif
809
810 /*
811 * If the process is currently idling in dt_proc_stop(), re-
812 * enable breakpoints and poke it into running again.
813 */
814 if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
815 dt_proc_bpenable(dpr);

--- 32 unchanged lines hidden (view full) ---

848 * libproc handle, and free our dt_proc_t data structure.
849 */
850 if (dpr->dpr_cacheable) {
851 assert(dph->dph_lrucnt != 0);
852 dph->dph_lrucnt--;
853 }
854
855 dt_list_delete(&dph->dph_lrulist, dpr);
815#endif
816
817 /*
818 * If the process is currently idling in dt_proc_stop(), re-
819 * enable breakpoints and poke it into running again.
820 */
821 if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
822 dt_proc_bpenable(dpr);

--- 32 unchanged lines hidden (view full) ---

855 * libproc handle, and free our dt_proc_t data structure.
856 */
857 if (dpr->dpr_cacheable) {
858 assert(dph->dph_lrucnt != 0);
859 dph->dph_lrucnt--;
860 }
861
862 dt_list_delete(&dph->dph_lrulist, dpr);
856#if defined(sun)
857 Prelease(dpr->dpr_proc, rflag);
863 Prelease(dpr->dpr_proc, rflag);
858#else
859 proc_detach(dpr->dpr_proc, rflag);
860#endif
861 dt_free(dtp, dpr);
862}
863
864static int
865dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
866{
867 dt_proc_control_data_t data;
868 sigset_t nset, oset;

--- 38 unchanged lines hidden (view full) ---

907 * reached the rendezvous event. This is either due to PS_LOST
908 * or PS_UNDEAD (i.e. the process died). We try to provide a
909 * small amount of useful information to help figure it out.
910 */
911 if (dpr->dpr_done) {
912#if defined(sun)
913 const psinfo_t *prp = Ppsinfo(dpr->dpr_proc);
914 int stat = prp ? prp->pr_wstat : 0;
864 dt_free(dtp, dpr);
865}
866
867static int
868dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
869{
870 dt_proc_control_data_t data;
871 sigset_t nset, oset;

--- 38 unchanged lines hidden (view full) ---

910 * reached the rendezvous event. This is either due to PS_LOST
911 * or PS_UNDEAD (i.e. the process died). We try to provide a
912 * small amount of useful information to help figure it out.
913 */
914 if (dpr->dpr_done) {
915#if defined(sun)
916 const psinfo_t *prp = Ppsinfo(dpr->dpr_proc);
917 int stat = prp ? prp->pr_wstat : 0;
915#endif
916 int pid = dpr->dpr_pid;
918 int pid = dpr->dpr_pid;
917
918#if defined(sun)
919 if (Pstate(dpr->dpr_proc) == PS_LOST) {
920#else
919#else
921 if (proc_state(dpr->dpr_proc) == PS_LOST) {
920 int stat = proc_getwstat(dpr->dpr_proc);
921 int pid = proc_getpid(dpr->dpr_proc);
922#endif
922#endif
923 if (proc_state(dpr->dpr_proc) == PS_LOST) {
923 (void) dt_proc_error(dpr->dpr_hdl, dpr,
924 "failed to control pid %d: process exec'd "
925 "set-id or unobservable program\n", pid);
924 (void) dt_proc_error(dpr->dpr_hdl, dpr,
925 "failed to control pid %d: process exec'd "
926 "set-id or unobservable program\n", pid);
926#if defined(sun)
927 } else if (WIFSIGNALED(stat)) {
928 (void) dt_proc_error(dpr->dpr_hdl, dpr,
929 "failed to control pid %d: process died "
930 "from signal %d\n", pid, WTERMSIG(stat));
931 } else {
932 (void) dt_proc_error(dpr->dpr_hdl, dpr,
933 "failed to control pid %d: process exited "
934 "with status %d\n", pid, WEXITSTATUS(stat));
927 } else if (WIFSIGNALED(stat)) {
928 (void) dt_proc_error(dpr->dpr_hdl, dpr,
929 "failed to control pid %d: process died "
930 "from signal %d\n", pid, WTERMSIG(stat));
931 } else {
932 (void) dt_proc_error(dpr->dpr_hdl, dpr,
933 "failed to control pid %d: process exited "
934 "with status %d\n", pid, WEXITSTATUS(stat));
935#endif
936 }
937
938 err = ESRCH; /* cause grab() or create() to fail */
939 }
940 } else {
941 (void) dt_proc_error(dpr->dpr_hdl, dpr,
942 "failed to create control thread for process-id %d: %s\n",
943 (int)dpr->dpr_pid, strerror(err));

--- 16 unchanged lines hidden (view full) ---

960 if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
961 return (NULL); /* errno is set for us */
962
963 (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
964 (void) pthread_cond_init(&dpr->dpr_cv, NULL);
965
966#if defined(sun)
967 if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
935 }
936
937 err = ESRCH; /* cause grab() or create() to fail */
938 }
939 } else {
940 (void) dt_proc_error(dpr->dpr_hdl, dpr,
941 "failed to create control thread for process-id %d: %s\n",
942 (int)dpr->dpr_pid, strerror(err));

--- 16 unchanged lines hidden (view full) ---

959 if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
960 return (NULL); /* errno is set for us */
961
962 (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
963 (void) pthread_cond_init(&dpr->dpr_cv, NULL);
964
965#if defined(sun)
966 if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
967#else
968 if ((err = proc_create(file, argv, pcf, child_arg,
969 &dpr->dpr_proc)) != 0) {
970#endif
968 return (dt_proc_error(dtp, dpr,
969 "failed to execute %s: %s\n", file, Pcreate_error(err)));
970 }
971
972 dpr->dpr_hdl = dtp;
971 return (dt_proc_error(dtp, dpr,
972 "failed to execute %s: %s\n", file, Pcreate_error(err)));
973 }
974
975 dpr->dpr_hdl = dtp;
976#if defined(sun)
973 dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid;
977 dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid;
974
975 (void) Punsetflags(dpr->dpr_proc, PR_RLC);
976 (void) Psetflags(dpr->dpr_proc, PR_KLC);
977#else
978#else
978 (void) proc_clearflags(dpr->dpr_proc, PR_RLC);
979 (void) proc_setflags(dpr->dpr_proc, PR_KLC);
980 if ((err = proc_create(file, argv, pcf, child_arg, &dpr->dpr_proc)) != 0)
981 return (dt_proc_error(dtp, dpr,
982 "failed to execute %s: %s\n", file, strerror(err)));
983 dpr->dpr_hdl = dtp;
984 dpr->dpr_pid = proc_getpid(dpr->dpr_proc);
985#endif
986
979 dpr->dpr_pid = proc_getpid(dpr->dpr_proc);
980#endif
981
987#if defined(sun)
982 (void) Punsetflags(dpr->dpr_proc, PR_RLC);
983 (void) Psetflags(dpr->dpr_proc, PR_KLC);
984
988 if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0)
985 if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0)
989#else
990 if (dt_proc_create_thread(dtp, dpr, DT_PROC_STOP_IDLE) != 0)
991#endif
992 return (NULL); /* dt_proc_error() has been called for us */
993
994 dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)];
995 dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)] = dpr;
996 dt_list_prepend(&dph->dph_lrulist, dpr);
997
998 dt_dprintf("created pid %d\n", (int)dpr->dpr_pid);
999 dpr->dpr_refs++;

--- 41 unchanged lines hidden (view full) ---

1041 if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
1042 return (NULL); /* errno is set for us */
1043
1044 (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
1045 (void) pthread_cond_init(&dpr->dpr_cv, NULL);
1046
1047#if defined(sun)
1048 if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) {
986 return (NULL); /* dt_proc_error() has been called for us */
987
988 dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)];
989 dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)] = dpr;
990 dt_list_prepend(&dph->dph_lrulist, dpr);
991
992 dt_dprintf("created pid %d\n", (int)dpr->dpr_pid);
993 dpr->dpr_refs++;

--- 41 unchanged lines hidden (view full) ---

1035 if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
1036 return (NULL); /* errno is set for us */
1037
1038 (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
1039 (void) pthread_cond_init(&dpr->dpr_cv, NULL);
1040
1041#if defined(sun)
1042 if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) {
1043#else
1044 if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) {
1045#endif
1049 return (dt_proc_error(dtp, dpr,
1050 "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err)));
1051 }
1046 return (dt_proc_error(dtp, dpr,
1047 "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err)));
1048 }
1052#else
1053 if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0)
1054 return (dt_proc_error(dtp, dpr,
1055 "failed to grab pid %d: %s\n", (int) pid, strerror(err)));
1056#endif
1057
1058 dpr->dpr_hdl = dtp;
1059 dpr->dpr_pid = pid;
1060
1049
1050 dpr->dpr_hdl = dtp;
1051 dpr->dpr_pid = pid;
1052
1061#if defined(sun)
1062 (void) Punsetflags(dpr->dpr_proc, PR_KLC);
1063 (void) Psetflags(dpr->dpr_proc, PR_RLC);
1053 (void) Punsetflags(dpr->dpr_proc, PR_KLC);
1054 (void) Psetflags(dpr->dpr_proc, PR_RLC);
1064#else
1065 (void) proc_clearflags(dpr->dpr_proc, PR_KLC);
1066 (void) proc_setflags(dpr->dpr_proc, PR_RLC);
1067#endif
1068
1069 /*
1070 * If we are attempting to grab the process without a monitor
1071 * thread, then mark the process cacheable only if it's being
1072 * grabbed read-only. If we're currently caching more process
1073 * handles than dph_lrulim permits, attempt to find the
1074 * least-recently-used handle that is currently unreferenced and
1075 * release it from the cache. Otherwise we are grabbing the process

--- 104 unchanged lines hidden (view full) ---

1180
1181struct ps_prochandle *
1182dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
1183 proc_child_func *pcf, void *child_arg)
1184{
1185 dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
1186 struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
1187
1055
1056 /*
1057 * If we are attempting to grab the process without a monitor
1058 * thread, then mark the process cacheable only if it's being
1059 * grabbed read-only. If we're currently caching more process
1060 * handles than dph_lrulim permits, attempt to find the
1061 * least-recently-used handle that is currently unreferenced and
1062 * release it from the cache. Otherwise we are grabbing the process

--- 104 unchanged lines hidden (view full) ---

1167
1168struct ps_prochandle *
1169dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
1170 proc_child_func *pcf, void *child_arg)
1171{
1172 dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
1173 struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
1174
1188 if (P != NULL && idp != NULL && idp->di_id == 0)
1175 if (P != NULL && idp != NULL && idp->di_id == 0) {
1189#if defined(sun)
1190 idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */
1191#else
1192 idp->di_id = proc_getpid(P); /* $target = created pid */
1193#endif
1176#if defined(sun)
1177 idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */
1178#else
1179 idp->di_id = proc_getpid(P); /* $target = created pid */
1180#endif
1181 }
1194
1195 return (P);
1196}
1197
1198struct ps_prochandle *
1199dtrace_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags)
1200{
1201 dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");

--- 19 unchanged lines hidden ---
1182
1183 return (P);
1184}
1185
1186struct ps_prochandle *
1187dtrace_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags)
1188{
1189 dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");

--- 19 unchanged lines hidden ---