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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2012 by Delphix. All rights reserved.
32 * DTrace Process Control
34 * This file provides a set of routines that permit libdtrace and its clients
35 * to create and grab process handles using libproc, and to share these handles
36 * between library mechanisms that need libproc access, such as ustack(), and
37 * client mechanisms that need libproc access, such as dtrace(1M) -c and -p.
38 * The library provides several mechanisms in the libproc control layer:
40 * Reference Counting: The library code and client code can independently grab
41 * the same process handles without interfering with one another. Only when
42 * the reference count drops to zero and the handle is not being cached (see
43 * below for more information on caching) will Prelease() be called on it.
45 * Handle Caching: If a handle is grabbed PGRAB_RDONLY (e.g. by ustack()) and
46 * the reference count drops to zero, the handle is not immediately released.
47 * Instead, libproc handles are maintained on dph_lrulist in order from most-
48 * recently accessed to least-recently accessed. Idle handles are maintained
49 * until a pre-defined LRU cache limit is exceeded, permitting repeated calls
50 * to ustack() to avoid the overhead of releasing and re-grabbing processes.
52 * Process Control: For processes that are grabbed for control (~PGRAB_RDONLY)
53 * or created by dt_proc_create(), a control thread is created to provide
54 * callbacks on process exit and symbol table caching on dlopen()s.
56 * MT-Safety: Libproc is not MT-Safe, so dt_proc_lock() and dt_proc_unlock()
57 * are provided to synchronize access to the libproc handle between libdtrace
58 * code and client code and the control thread's use of the ps_prochandle.
60 * NOTE: MT-Safety is NOT provided for libdtrace itself, or for use of the
61 * dtrace_proc_grab/dtrace_proc_create mechanisms. Like all exported libdtrace
62 * calls, these are assumed to be MT-Unsafe. MT-Safety is ONLY provided for
63 * synchronization between libdtrace control threads and the client thread.
65 * The ps_prochandles themselves are maintained along with a dt_proc_t struct
66 * in a hash table indexed by PID. This provides basic locking and reference
67 * counting. The dt_proc_t is also maintained in LRU order on dph_lrulist.
68 * The dph_lrucnt and dph_lrulim count the number of cacheable processes and
69 * the current limit on the number of actively cached entries.
71 * The control thread for a process establishes breakpoints at the rtld_db
72 * locations of interest, updates mappings and symbol tables at these points,
73 * and handles exec and fork (by always following the parent). The control
74 * thread automatically exits when the process dies or control is lost.
76 * A simple notification mechanism is provided for libdtrace clients using
77 * dtrace_handle_proc() for notification of PS_UNDEAD or PS_LOST events. If
78 * such an event occurs, the dt_proc_t itself is enqueued on a notification
79 * list and the control thread broadcasts to dph_cv. dtrace_sleep() will wake
80 * up using this condition and will then call the client handler as necessary.
95 #define IS_SYS_EXEC(w) (w == SYS_execve)
96 #define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
99 dt_proc_bpcreate(dt_proc_t
*dpr
, uintptr_t addr
, dt_bkpt_f
*func
, void *data
)
101 struct ps_prochandle
*P
= dpr
->dpr_proc
;
104 assert(MUTEX_HELD(&dpr
->dpr_lock
));
106 if ((dbp
= dt_zalloc(dpr
->dpr_hdl
, sizeof (dt_bkpt_t
))) != NULL
) {
107 dbp
->dbp_func
= func
;
108 dbp
->dbp_data
= data
;
109 dbp
->dbp_addr
= addr
;
111 if (Psetbkpt(P
, dbp
->dbp_addr
, &dbp
->dbp_instr
) == 0)
112 dbp
->dbp_active
= B_TRUE
;
114 dt_list_append(&dpr
->dpr_bps
, dbp
);
121 dt_proc_bpdestroy(dt_proc_t
*dpr
, int delbkpts
)
123 int state
= Pstate(dpr
->dpr_proc
);
124 dt_bkpt_t
*dbp
, *nbp
;
126 assert(MUTEX_HELD(&dpr
->dpr_lock
));
128 for (dbp
= dt_list_next(&dpr
->dpr_bps
); dbp
!= NULL
; dbp
= nbp
) {
129 if (delbkpts
&& dbp
->dbp_active
&&
130 state
!= PS_LOST
&& state
!= PS_UNDEAD
) {
131 (void) Pdelbkpt(dpr
->dpr_proc
,
132 dbp
->dbp_addr
, dbp
->dbp_instr
);
134 nbp
= dt_list_next(dbp
);
135 dt_list_delete(&dpr
->dpr_bps
, dbp
);
136 dt_free(dpr
->dpr_hdl
, dbp
);
141 dt_proc_bpmatch(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
)
143 const lwpstatus_t
*psp
= &Pstatus(dpr
->dpr_proc
)->pr_lwp
;
146 assert(MUTEX_HELD(&dpr
->dpr_lock
));
148 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
149 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
150 if (psp
->pr_reg
[R_PC
] == dbp
->dbp_addr
)
155 dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
156 (int)dpr
->dpr_pid
, (ulong_t
)psp
->pr_reg
[R_PC
]);
160 dt_dprintf("pid %d: hit breakpoint at %lx (%lu)\n",
161 (int)dpr
->dpr_pid
, (ulong_t
)dbp
->dbp_addr
, ++dbp
->dbp_hits
);
163 dbp
->dbp_func(dtp
, dpr
, dbp
->dbp_data
);
164 (void) Pxecbkpt(dpr
->dpr_proc
, dbp
->dbp_instr
);
168 dt_proc_bpenable(dt_proc_t
*dpr
)
172 assert(MUTEX_HELD(&dpr
->dpr_lock
));
174 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
175 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
176 if (!dbp
->dbp_active
&& Psetbkpt(dpr
->dpr_proc
,
177 dbp
->dbp_addr
, &dbp
->dbp_instr
) == 0)
178 dbp
->dbp_active
= B_TRUE
;
181 dt_dprintf("breakpoints enabled\n");
185 dt_proc_bpdisable(dt_proc_t
*dpr
)
189 assert(MUTEX_HELD(&dpr
->dpr_lock
));
191 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
192 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
193 if (dbp
->dbp_active
&& Pdelbkpt(dpr
->dpr_proc
,
194 dbp
->dbp_addr
, dbp
->dbp_instr
) == 0)
195 dbp
->dbp_active
= B_FALSE
;
198 dt_dprintf("breakpoints disabled\n");
202 dt_proc_notify(dtrace_hdl_t
*dtp
, dt_proc_hash_t
*dph
, dt_proc_t
*dpr
,
205 dt_proc_notify_t
*dprn
= dt_alloc(dtp
, sizeof (dt_proc_notify_t
));
208 dt_dprintf("failed to allocate notification for %d %s\n",
209 (int)dpr
->dpr_pid
, msg
);
211 dprn
->dprn_dpr
= dpr
;
213 dprn
->dprn_errmsg
[0] = '\0';
215 (void) strlcpy(dprn
->dprn_errmsg
, msg
,
216 sizeof (dprn
->dprn_errmsg
));
218 (void) pthread_mutex_lock(&dph
->dph_lock
);
220 dprn
->dprn_next
= dph
->dph_notify
;
221 dph
->dph_notify
= dprn
;
223 (void) pthread_cond_broadcast(&dph
->dph_cv
);
224 (void) pthread_mutex_unlock(&dph
->dph_lock
);
229 * Check to see if the control thread was requested to stop when the victim
230 * process reached a particular event (why) rather than continuing the victim.
231 * If 'why' is set in the stop mask, we wait on dpr_cv for dt_proc_continue().
232 * If 'why' is not set, this function returns immediately and does nothing.
235 dt_proc_stop(dt_proc_t
*dpr
, uint8_t why
)
237 assert(MUTEX_HELD(&dpr
->dpr_lock
));
238 assert(why
!= DT_PROC_STOP_IDLE
);
240 if (dpr
->dpr_stop
& why
) {
241 dpr
->dpr_stop
|= DT_PROC_STOP_IDLE
;
242 dpr
->dpr_stop
&= ~why
;
244 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
247 * We disable breakpoints while stopped to preserve the
248 * integrity of the program text for both our own disassembly
249 * and that of the kernel.
251 dt_proc_bpdisable(dpr
);
253 while (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
)
254 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
256 dt_proc_bpenable(dpr
);
262 dt_proc_bpmain(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *fname
)
264 dt_dprintf("pid %d: breakpoint at %s()\n", (int)dpr
->dpr_pid
, fname
);
265 dt_proc_stop(dpr
, DT_PROC_STOP_MAIN
);
269 dt_proc_rdevent(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *evname
)
274 if ((err
= rd_event_getmsg(dpr
->dpr_rtld
, &rdm
)) != RD_OK
) {
275 dt_dprintf("pid %d: failed to get %s event message: %s\n",
276 (int)dpr
->dpr_pid
, evname
, rd_errstr(err
));
280 dt_dprintf("pid %d: rtld event %s type=%d state %d\n",
281 (int)dpr
->dpr_pid
, evname
, rdm
.type
, rdm
.u
.state
);
285 if (rdm
.u
.state
!= RD_CONSISTENT
)
288 Pupdate_syms(dpr
->dpr_proc
);
289 if (dt_pid_create_probes_module(dtp
, dpr
) != 0)
290 dt_proc_notify(dtp
, dtp
->dt_procs
, dpr
,
295 Pupdate_syms(dpr
->dpr_proc
);
296 dt_proc_stop(dpr
, DT_PROC_STOP_PREINIT
);
299 Pupdate_syms(dpr
->dpr_proc
);
300 dt_proc_stop(dpr
, DT_PROC_STOP_POSTINIT
);
306 dt_proc_rdwatch(dt_proc_t
*dpr
, rd_event_e event
, const char *evname
)
311 if ((err
= rd_event_addr(dpr
->dpr_rtld
, event
, &rdn
)) != RD_OK
) {
312 dt_dprintf("pid %d: failed to get event address for %s: %s\n",
313 (int)dpr
->dpr_pid
, evname
, rd_errstr(err
));
317 if (rdn
.type
!= RD_NOTIFY_BPT
) {
318 dt_dprintf("pid %d: event %s has unexpected type %d\n",
319 (int)dpr
->dpr_pid
, evname
, rdn
.type
);
323 (void) dt_proc_bpcreate(dpr
, rdn
.u
.bptaddr
,
324 (dt_bkpt_f
*)dt_proc_rdevent
, (void *)evname
);
328 * Common code for enabling events associated with the run-time linker after
329 * attaching to a process or after a victim process completes an exec(2).
332 dt_proc_attach(dt_proc_t
*dpr
, int exec
)
334 const pstatus_t
*psp
= Pstatus(dpr
->dpr_proc
);
338 assert(MUTEX_HELD(&dpr
->dpr_lock
));
341 if (psp
->pr_lwp
.pr_errno
!= 0)
342 return; /* exec failed: nothing needs to be done */
344 dt_proc_bpdestroy(dpr
, B_FALSE
);
345 Preset_maps(dpr
->dpr_proc
);
348 if ((dpr
->dpr_rtld
= Prd_agent(dpr
->dpr_proc
)) != NULL
&&
349 (err
= rd_event_enable(dpr
->dpr_rtld
, B_TRUE
)) == RD_OK
) {
350 dt_proc_rdwatch(dpr
, RD_PREINIT
, "RD_PREINIT");
351 dt_proc_rdwatch(dpr
, RD_POSTINIT
, "RD_POSTINIT");
352 dt_proc_rdwatch(dpr
, RD_DLACTIVITY
, "RD_DLACTIVITY");
354 dt_dprintf("pid %d: failed to enable rtld events: %s\n",
355 (int)dpr
->dpr_pid
, dpr
->dpr_rtld
? rd_errstr(err
) :
356 "rtld_db agent initialization failed");
359 Pupdate_maps(dpr
->dpr_proc
);
361 if (Pxlookup_by_name(dpr
->dpr_proc
, LM_ID_BASE
,
362 "a.out", "main", &sym
, NULL
) == 0) {
363 (void) dt_proc_bpcreate(dpr
, (uintptr_t)sym
.st_value
,
364 (dt_bkpt_f
*)dt_proc_bpmain
, "a.out`main");
366 dt_dprintf("pid %d: failed to find a.out`main: %s\n",
367 (int)dpr
->dpr_pid
, strerror(errno
));
372 * Wait for a stopped process to be set running again by some other debugger.
373 * This is typically not required by /proc-based debuggers, since the usual
374 * model is that one debugger controls one victim. But DTrace, as usual, has
375 * its own needs: the stop() action assumes that prun(1) or some other tool
376 * will be applied to resume the victim process. This could be solved by
377 * adding a PCWRUN directive to /proc, but that seems like overkill unless
378 * other debuggers end up needing this functionality, so we implement a cheap
379 * equivalent to PCWRUN using the set of existing kernel mechanisms.
381 * Our intent is really not just to wait for the victim to run, but rather to
382 * wait for it to run and then stop again for a reason other than the current
383 * PR_REQUESTED stop. Since PCWSTOP/Pstopstatus() can be applied repeatedly
384 * to a stopped process and will return the same result without affecting the
385 * victim, we can just perform these operations repeatedly until Pstate()
386 * changes, the representative LWP ID changes, or the stop timestamp advances.
387 * dt_proc_control() will then rediscover the new state and continue as usual.
388 * When the process is still stopped in the same exact state, we sleep for a
389 * brief interval before waiting again so as not to spin consuming CPU cycles.
392 dt_proc_waitrun(dt_proc_t
*dpr
)
394 struct ps_prochandle
*P
= dpr
->dpr_proc
;
395 const lwpstatus_t
*psp
= &Pstatus(P
)->pr_lwp
;
397 int krflag
= psp
->pr_flags
& (PR_KLC
| PR_RLC
);
398 timestruc_t tstamp
= psp
->pr_tstamp
;
399 lwpid_t lwpid
= psp
->pr_lwpid
;
401 const long wstop
= PCWSTOP
;
404 assert(MUTEX_HELD(&dpr
->dpr_lock
));
405 assert(psp
->pr_flags
& PR_STOPPED
);
406 assert(Pstate(P
) == PS_STOP
);
409 * While we are waiting for the victim to run, clear PR_KLC and PR_RLC
410 * so that if the libdtrace client is killed, the victim stays stopped.
411 * dt_proc_destroy() will also observe this and perform PRELEASE_HANG.
413 (void) Punsetflags(P
, krflag
);
416 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
418 while (!dpr
->dpr_quit
) {
419 if (write(pfd
, &wstop
, sizeof (wstop
)) == -1 && errno
== EINTR
)
420 continue; /* check dpr_quit and continue waiting */
422 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
423 (void) Pstopstatus(P
, PCNULL
, 0);
424 psp
= &Pstatus(P
)->pr_lwp
;
427 * If we've reached a new state, found a new representative, or
428 * the stop timestamp has changed, restore PR_KLC/PR_RLC to its
429 * original setting and then return with dpr_lock held.
431 if (Pstate(P
) != PS_STOP
|| psp
->pr_lwpid
!= lwpid
||
432 bcmp(&psp
->pr_tstamp
, &tstamp
, sizeof (tstamp
)) != 0) {
433 (void) Psetflags(P
, krflag
);
438 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
439 (void) poll(NULL
, 0, MILLISEC
/ 2);
442 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
445 typedef struct dt_proc_control_data
{
446 dtrace_hdl_t
*dpcd_hdl
; /* DTrace handle */
447 dt_proc_t
*dpcd_proc
; /* proccess to control */
448 } dt_proc_control_data_t
;
451 * Main loop for all victim process control threads. We initialize all the
452 * appropriate /proc control mechanisms, and then enter a loop waiting for
453 * the process to stop on an event or die. We process any events by calling
454 * appropriate subroutines, and exit when the victim dies or we lose control.
456 * The control thread synchronizes the use of dpr_proc with other libdtrace
457 * threads using dpr_lock. We hold the lock for all of our operations except
458 * waiting while the process is running: this is accomplished by writing a
459 * PCWSTOP directive directly to the underlying /proc/<pid>/ctl file. If the
460 * libdtrace client wishes to exit or abort our wait, SIGCANCEL can be used.
463 dt_proc_control(void *arg
)
465 dt_proc_control_data_t
*datap
= arg
;
466 dtrace_hdl_t
*dtp
= datap
->dpcd_hdl
;
467 dt_proc_t
*dpr
= datap
->dpcd_proc
;
468 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
469 struct ps_prochandle
*P
= dpr
->dpr_proc
;
472 int pid
= dpr
->dpr_pid
;
474 const long wstop
= PCWSTOP
;
475 int notify
= B_FALSE
;
478 * We disable the POSIX thread cancellation mechanism so that the
479 * client program using libdtrace can't accidentally cancel our thread.
480 * dt_proc_destroy() uses SIGCANCEL explicitly to simply poke us out
481 * of PCWSTOP with EINTR, at which point we will see dpr_quit and exit.
483 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
486 * Set up the corresponding process for tracing by libdtrace. We want
487 * to be able to catch breakpoints and efficiently single-step over
488 * them, and we need to enable librtld_db to watch libdl activity.
490 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
492 (void) Punsetflags(P
, PR_ASYNC
); /* require synchronous mode */
493 (void) Psetflags(P
, PR_BPTADJ
); /* always adjust eip on x86 */
494 (void) Punsetflags(P
, PR_FORK
); /* do not inherit on fork */
496 (void) Pfault(P
, FLTBPT
, B_TRUE
); /* always trace breakpoints */
497 (void) Pfault(P
, FLTTRACE
, B_TRUE
); /* always trace single-step */
500 * We must trace exit from exec() system calls so that if the exec is
501 * successful, we can reset our breakpoints and re-initialize libproc.
503 (void) Psysexit(P
, SYS_execve
, B_TRUE
);
506 * We must trace entry and exit for fork() system calls in order to
507 * disable our breakpoints temporarily during the fork. We do not set
508 * the PR_FORK flag, so if fork succeeds the child begins executing and
509 * does not inherit any other tracing behaviors or a control thread.
511 (void) Psysentry(P
, SYS_vfork
, B_TRUE
);
512 (void) Psysexit(P
, SYS_vfork
, B_TRUE
);
513 (void) Psysentry(P
, SYS_forksys
, B_TRUE
);
514 (void) Psysexit(P
, SYS_forksys
, B_TRUE
);
516 Psync(P
); /* enable all /proc changes */
517 dt_proc_attach(dpr
, B_FALSE
); /* enable rtld breakpoints */
520 * If PR_KLC is set, we created the process; otherwise we grabbed it.
521 * Check for an appropriate stop request and wait for dt_proc_continue.
523 if (Pstatus(P
)->pr_flags
& PR_KLC
)
524 dt_proc_stop(dpr
, DT_PROC_STOP_CREATE
);
526 dt_proc_stop(dpr
, DT_PROC_STOP_GRAB
);
528 if (Psetrun(P
, 0, 0) == -1) {
529 dt_dprintf("pid %d: failed to set running: %s\n",
530 (int)dpr
->dpr_pid
, strerror(errno
));
533 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
536 * Wait for the process corresponding to this control thread to stop,
537 * process the event, and then set it running again. We want to sleep
538 * with dpr_lock *unheld* so that other parts of libdtrace can use the
539 * ps_prochandle in the meantime (e.g. ustack()). To do this, we write
540 * a PCWSTOP directive directly to the underlying /proc/<pid>/ctl file.
541 * Once the process stops, we wake up, grab dpr_lock, and then call
542 * Pwait() (which will return immediately) and do our processing.
544 while (!dpr
->dpr_quit
) {
545 const lwpstatus_t
*psp
;
547 if (write(pfd
, &wstop
, sizeof (wstop
)) == -1 && errno
== EINTR
)
548 continue; /* check dpr_quit and continue waiting */
550 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
552 if (Pstopstatus(P
, PCNULL
, 0) == -1 && errno
== EINTR
) {
553 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
554 continue; /* check dpr_quit and continue waiting */
559 psp
= &Pstatus(P
)->pr_lwp
;
561 dt_dprintf("pid %d: proc stopped showing %d/%d\n",
562 pid
, psp
->pr_why
, psp
->pr_what
);
565 * If the process stops showing PR_REQUESTED, then the
566 * DTrace stop() action was applied to it or another
567 * debugging utility (e.g. pstop(1)) asked it to stop.
568 * In either case, the user's intention is for the
569 * process to remain stopped until another external
570 * mechanism (e.g. prun(1)) is applied. So instead of
571 * setting the process running ourself, we wait for
572 * someone else to do so. Once that happens, we return
573 * to our normal loop waiting for an event of interest.
575 if (psp
->pr_why
== PR_REQUESTED
) {
576 dt_proc_waitrun(dpr
);
577 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
582 * If the process stops showing one of the events that
583 * we are tracing, perform the appropriate response.
584 * Note that we ignore PR_SUSPENDED, PR_CHECKPOINT, and
585 * PR_JOBCONTROL by design: if one of these conditions
586 * occurs, we will fall through to Psetrun() but the
587 * process will remain stopped in the kernel by the
588 * corresponding mechanism (e.g. job control stop).
590 if (psp
->pr_why
== PR_FAULTED
&& psp
->pr_what
== FLTBPT
)
591 dt_proc_bpmatch(dtp
, dpr
);
592 else if (psp
->pr_why
== PR_SYSENTRY
&&
593 IS_SYS_FORK(psp
->pr_what
))
594 dt_proc_bpdisable(dpr
);
595 else if (psp
->pr_why
== PR_SYSEXIT
&&
596 IS_SYS_FORK(psp
->pr_what
))
597 dt_proc_bpenable(dpr
);
598 else if (psp
->pr_why
== PR_SYSEXIT
&&
599 IS_SYS_EXEC(psp
->pr_what
))
600 dt_proc_attach(dpr
, B_TRUE
);
607 dt_dprintf("pid %d: proc lost: %s\n",
608 pid
, strerror(errno
));
610 dpr
->dpr_quit
= B_TRUE
;
615 dt_dprintf("pid %d: proc died\n", pid
);
616 dpr
->dpr_quit
= B_TRUE
;
621 if (Pstate(P
) != PS_UNDEAD
&& Psetrun(P
, 0, 0) == -1) {
622 dt_dprintf("pid %d: failed to set running: %s\n",
623 (int)dpr
->dpr_pid
, strerror(errno
));
626 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
630 * If the control thread detected PS_UNDEAD or PS_LOST, then enqueue
631 * the dt_proc_t structure on the dt_proc_hash_t notification list.
634 dt_proc_notify(dtp
, dph
, dpr
, NULL
);
637 * Destroy and remove any remaining breakpoints, set dpr_done and clear
638 * dpr_tid to indicate the control thread has exited, and notify any
639 * waiting thread in dt_proc_destroy() that we have succesfully exited.
641 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
643 dt_proc_bpdestroy(dpr
, B_TRUE
);
644 dpr
->dpr_done
= B_TRUE
;
647 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
648 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
654 static struct ps_prochandle
*
655 dt_proc_error(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *format
, ...)
659 va_start(ap
, format
);
660 dt_set_errmsg(dtp
, NULL
, NULL
, NULL
, 0, format
, ap
);
663 if (dpr
->dpr_proc
!= NULL
)
664 Prelease(dpr
->dpr_proc
, 0);
667 (void) dt_set_errno(dtp
, EDT_COMPILER
);
672 dt_proc_lookup(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
, int remove
)
674 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
675 pid_t pid
= Pstatus(P
)->pr_pid
;
676 dt_proc_t
*dpr
, **dpp
= &dph
->dph_hash
[pid
& (dph
->dph_hashlen
- 1)];
678 for (dpr
= *dpp
; dpr
!= NULL
; dpr
= dpr
->dpr_hash
) {
679 if (dpr
->dpr_pid
== pid
)
682 dpp
= &dpr
->dpr_hash
;
686 assert(dpr
->dpr_proc
== P
);
689 *dpp
= dpr
->dpr_hash
; /* remove from pid hash chain */
695 dt_proc_destroy(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
697 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
698 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
699 dt_proc_notify_t
*npr
, **npp
;
705 * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
706 * an external debugger and we were waiting in dt_proc_waitrun().
707 * Leave the process in this condition using PRELEASE_HANG.
709 if (!(Pstatus(dpr
->dpr_proc
)->pr_flags
& (PR_KLC
| PR_RLC
))) {
710 dt_dprintf("abandoning pid %d\n", (int)dpr
->dpr_pid
);
711 rflag
= PRELEASE_HANG
;
712 } else if (Pstatus(dpr
->dpr_proc
)->pr_flags
& PR_KLC
) {
713 dt_dprintf("killing pid %d\n", (int)dpr
->dpr_pid
);
714 rflag
= PRELEASE_KILL
; /* apply kill-on-last-close */
716 dt_dprintf("releasing pid %d\n", (int)dpr
->dpr_pid
);
717 rflag
= 0; /* apply run-on-last-close */
722 * Set the dpr_quit flag to tell the daemon thread to exit. We
723 * send it a SIGCANCEL to poke it out of PCWSTOP or any other
724 * long-term /proc system call. Our daemon threads have POSIX
725 * cancellation disabled, so EINTR will be the only effect. We
726 * then wait for dpr_done to indicate the thread has exited.
728 * We can't use pthread_kill() to send SIGCANCEL because the
729 * interface forbids it and we can't use pthread_cancel()
730 * because with cancellation disabled it won't actually
731 * send SIGCANCEL to the target thread, so we use _lwp_kill()
732 * to do the job. This is all built on evil knowledge of
733 * the details of the cancellation mechanism in libc.
735 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
736 dpr
->dpr_quit
= B_TRUE
;
737 (void) _lwp_kill(dpr
->dpr_tid
, SIGCANCEL
);
740 * If the process is currently idling in dt_proc_stop(), re-
741 * enable breakpoints and poke it into running again.
743 if (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
) {
744 dt_proc_bpenable(dpr
);
745 dpr
->dpr_stop
&= ~DT_PROC_STOP_IDLE
;
746 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
749 while (!dpr
->dpr_done
)
750 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
752 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
756 * Before we free the process structure, remove this dt_proc_t from the
757 * lookup hash, and then walk the dt_proc_hash_t's notification list
758 * and remove this dt_proc_t if it is enqueued.
760 (void) pthread_mutex_lock(&dph
->dph_lock
);
761 (void) dt_proc_lookup(dtp
, P
, B_TRUE
);
762 npp
= &dph
->dph_notify
;
764 while ((npr
= *npp
) != NULL
) {
765 if (npr
->dprn_dpr
== dpr
) {
766 *npp
= npr
->dprn_next
;
769 npp
= &npr
->dprn_next
;
773 (void) pthread_mutex_unlock(&dph
->dph_lock
);
776 * Remove the dt_proc_list from the LRU list, release the underlying
777 * libproc handle, and free our dt_proc_t data structure.
779 if (dpr
->dpr_cacheable
) {
780 assert(dph
->dph_lrucnt
!= 0);
784 dt_list_delete(&dph
->dph_lrulist
, dpr
);
785 Prelease(dpr
->dpr_proc
, rflag
);
790 dt_proc_create_thread(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, uint_t stop
)
792 dt_proc_control_data_t data
;
797 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
798 dpr
->dpr_stop
|= stop
; /* set bit for initial rendezvous */
800 (void) pthread_attr_init(&a
);
801 (void) pthread_attr_setdetachstate(&a
, PTHREAD_CREATE_DETACHED
);
803 (void) sigfillset(&nset
);
804 (void) sigdelset(&nset
, SIGABRT
); /* unblocked for assert() */
805 (void) sigdelset(&nset
, SIGCANCEL
); /* see dt_proc_destroy() */
808 data
.dpcd_proc
= dpr
;
810 (void) pthread_sigmask(SIG_SETMASK
, &nset
, &oset
);
811 err
= pthread_create(&dpr
->dpr_tid
, &a
, dt_proc_control
, &data
);
812 (void) pthread_sigmask(SIG_SETMASK
, &oset
, NULL
);
815 * If the control thread was created, then wait on dpr_cv for either
816 * dpr_done to be set (the victim died or the control thread failed)
817 * or DT_PROC_STOP_IDLE to be set, indicating that the victim is now
818 * stopped by /proc and the control thread is at the rendezvous event.
819 * On success, we return with the process and control thread stopped:
820 * the caller can then apply dt_proc_continue() to resume both.
823 while (!dpr
->dpr_done
&& !(dpr
->dpr_stop
& DT_PROC_STOP_IDLE
))
824 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
827 * If dpr_done is set, the control thread aborted before it
828 * reached the rendezvous event. This is either due to PS_LOST
829 * or PS_UNDEAD (i.e. the process died). We try to provide a
830 * small amount of useful information to help figure it out.
833 const psinfo_t
*prp
= Ppsinfo(dpr
->dpr_proc
);
834 int stat
= prp
? prp
->pr_wstat
: 0;
835 int pid
= dpr
->dpr_pid
;
837 if (Pstate(dpr
->dpr_proc
) == PS_LOST
) {
838 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
839 "failed to control pid %d: process exec'd "
840 "set-id or unobservable program\n", pid
);
841 } else if (WIFSIGNALED(stat
)) {
842 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
843 "failed to control pid %d: process died "
844 "from signal %d\n", pid
, WTERMSIG(stat
));
846 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
847 "failed to control pid %d: process exited "
848 "with status %d\n", pid
, WEXITSTATUS(stat
));
851 err
= ESRCH
; /* cause grab() or create() to fail */
854 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
855 "failed to create control thread for process-id %d: %s\n",
856 (int)dpr
->dpr_pid
, strerror(err
));
859 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
860 (void) pthread_attr_destroy(&a
);
865 struct ps_prochandle
*
866 dt_proc_create(dtrace_hdl_t
*dtp
, const char *file
, char *const *argv
)
868 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
872 if ((dpr
= dt_zalloc(dtp
, sizeof (dt_proc_t
))) == NULL
)
873 return (NULL
); /* errno is set for us */
875 (void) pthread_mutex_init(&dpr
->dpr_lock
, NULL
);
876 (void) pthread_cond_init(&dpr
->dpr_cv
, NULL
);
878 dpr
->dpr_proc
= Pxcreate(file
, argv
, dtp
->dt_proc_env
, &err
, NULL
, 0);
879 if (dpr
->dpr_proc
== NULL
) {
880 return (dt_proc_error(dtp
, dpr
,
881 "failed to execute %s: %s\n", file
, Pcreate_error(err
)));
885 dpr
->dpr_pid
= Pstatus(dpr
->dpr_proc
)->pr_pid
;
887 (void) Punsetflags(dpr
->dpr_proc
, PR_RLC
);
888 (void) Psetflags(dpr
->dpr_proc
, PR_KLC
);
890 if (dt_proc_create_thread(dtp
, dpr
, dtp
->dt_prcmode
) != 0)
891 return (NULL
); /* dt_proc_error() has been called for us */
893 dpr
->dpr_hash
= dph
->dph_hash
[dpr
->dpr_pid
& (dph
->dph_hashlen
- 1)];
894 dph
->dph_hash
[dpr
->dpr_pid
& (dph
->dph_hashlen
- 1)] = dpr
;
895 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
897 dt_dprintf("created pid %d\n", (int)dpr
->dpr_pid
);
900 return (dpr
->dpr_proc
);
903 struct ps_prochandle
*
904 dt_proc_grab(dtrace_hdl_t
*dtp
, pid_t pid
, int flags
, int nomonitor
)
906 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
907 uint_t h
= pid
& (dph
->dph_hashlen
- 1);
908 dt_proc_t
*dpr
, *opr
;
912 * Search the hash table for the pid. If it is already grabbed or
913 * created, move the handle to the front of the lrulist, increment
914 * the reference count, and return the existing ps_prochandle.
916 for (dpr
= dph
->dph_hash
[h
]; dpr
!= NULL
; dpr
= dpr
->dpr_hash
) {
917 if (dpr
->dpr_pid
== pid
&& !dpr
->dpr_stale
) {
919 * If the cached handle was opened read-only and
920 * this request is for a writeable handle, mark
921 * the cached handle as stale and open a new handle.
922 * Since it's stale, unmark it as cacheable.
924 if (dpr
->dpr_rdonly
&& !(flags
& PGRAB_RDONLY
)) {
925 dt_dprintf("upgrading pid %d\n", (int)pid
);
926 dpr
->dpr_stale
= B_TRUE
;
927 dpr
->dpr_cacheable
= B_FALSE
;
932 dt_dprintf("grabbed pid %d (cached)\n", (int)pid
);
933 dt_list_delete(&dph
->dph_lrulist
, dpr
);
934 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
936 return (dpr
->dpr_proc
);
940 if ((dpr
= dt_zalloc(dtp
, sizeof (dt_proc_t
))) == NULL
)
941 return (NULL
); /* errno is set for us */
943 (void) pthread_mutex_init(&dpr
->dpr_lock
, NULL
);
944 (void) pthread_cond_init(&dpr
->dpr_cv
, NULL
);
946 if ((dpr
->dpr_proc
= Pgrab(pid
, flags
, &err
)) == NULL
) {
947 return (dt_proc_error(dtp
, dpr
,
948 "failed to grab pid %d: %s\n", (int)pid
, Pgrab_error(err
)));
954 (void) Punsetflags(dpr
->dpr_proc
, PR_KLC
);
955 (void) Psetflags(dpr
->dpr_proc
, PR_RLC
);
958 * If we are attempting to grab the process without a monitor
959 * thread, then mark the process cacheable only if it's being
960 * grabbed read-only. If we're currently caching more process
961 * handles than dph_lrulim permits, attempt to find the
962 * least-recently-used handle that is currently unreferenced and
963 * release it from the cache. Otherwise we are grabbing the process
964 * for control: create a control thread for this process and store
965 * its ID in dpr->dpr_tid.
967 if (nomonitor
|| (flags
& PGRAB_RDONLY
)) {
968 if (dph
->dph_lrucnt
>= dph
->dph_lrulim
) {
969 for (opr
= dt_list_prev(&dph
->dph_lrulist
);
970 opr
!= NULL
; opr
= dt_list_prev(opr
)) {
971 if (opr
->dpr_cacheable
&& opr
->dpr_refs
== 0) {
972 dt_proc_destroy(dtp
, opr
->dpr_proc
);
978 if (flags
& PGRAB_RDONLY
) {
979 dpr
->dpr_cacheable
= B_TRUE
;
980 dpr
->dpr_rdonly
= B_TRUE
;
984 } else if (dt_proc_create_thread(dtp
, dpr
, DT_PROC_STOP_GRAB
) != 0)
985 return (NULL
); /* dt_proc_error() has been called for us */
987 dpr
->dpr_hash
= dph
->dph_hash
[h
];
988 dph
->dph_hash
[h
] = dpr
;
989 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
991 dt_dprintf("grabbed pid %d\n", (int)pid
);
994 return (dpr
->dpr_proc
);
998 dt_proc_release(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1000 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1001 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
1003 assert(dpr
!= NULL
);
1004 assert(dpr
->dpr_refs
!= 0);
1006 if (--dpr
->dpr_refs
== 0 &&
1007 (!dpr
->dpr_cacheable
|| dph
->dph_lrucnt
> dph
->dph_lrulim
))
1008 dt_proc_destroy(dtp
, P
);
1012 dt_proc_continue(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1014 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1016 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
1018 if (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
) {
1019 dpr
->dpr_stop
&= ~DT_PROC_STOP_IDLE
;
1020 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
1023 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
1027 dt_proc_lock(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1029 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1030 int err
= pthread_mutex_lock(&dpr
->dpr_lock
);
1031 assert(err
== 0); /* check for recursion */
1035 dt_proc_unlock(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1037 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1038 int err
= pthread_mutex_unlock(&dpr
->dpr_lock
);
1039 assert(err
== 0); /* check for unheld lock */
1043 dt_proc_init(dtrace_hdl_t
*dtp
)
1045 extern char **environ
;
1046 static char *envdef
[] = {
1047 "LD_NOLAZYLOAD=1", /* linker lazy loading hides funcs */
1053 if ((dtp
->dt_procs
= dt_zalloc(dtp
, sizeof (dt_proc_hash_t
) +
1054 sizeof (dt_proc_t
*) * _dtrace_pidbuckets
- 1)) == NULL
)
1057 (void) pthread_mutex_init(&dtp
->dt_procs
->dph_lock
, NULL
);
1058 (void) pthread_cond_init(&dtp
->dt_procs
->dph_cv
, NULL
);
1060 dtp
->dt_procs
->dph_hashlen
= _dtrace_pidbuckets
;
1061 dtp
->dt_procs
->dph_lrulim
= _dtrace_pidlrulim
;
1065 * Count how big our environment needs to be.
1067 for (i
= 1, p
= environ
; *p
!= NULL
; i
++, p
++)
1069 for (p
= envdef
; *p
!= NULL
; i
++, p
++)
1072 if ((dtp
->dt_proc_env
= dt_zalloc(dtp
, sizeof (char *) * i
)) == NULL
)
1075 for (i
= 0, p
= environ
; *p
!= NULL
; i
++, p
++) {
1076 if ((dtp
->dt_proc_env
[i
] = strdup(*p
)) == NULL
)
1079 for (p
= envdef
; *p
!= NULL
; i
++, p
++) {
1080 if ((dtp
->dt_proc_env
[i
] = strdup(*p
)) == NULL
)
1088 dt_free(dtp
, dtp
->dt_proc_env
[i
]);
1090 dt_free(dtp
, dtp
->dt_proc_env
);
1091 dtp
->dt_proc_env
= NULL
;
1095 dt_proc_fini(dtrace_hdl_t
*dtp
)
1097 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
1101 while ((dpr
= dt_list_next(&dph
->dph_lrulist
)) != NULL
)
1102 dt_proc_destroy(dtp
, dpr
->dpr_proc
);
1104 dtp
->dt_procs
= NULL
;
1107 for (p
= dtp
->dt_proc_env
; *p
!= NULL
; p
++)
1110 dt_free(dtp
, dtp
->dt_proc_env
);
1111 dtp
->dt_proc_env
= NULL
;
1114 struct ps_prochandle
*
1115 dtrace_proc_create(dtrace_hdl_t
*dtp
, const char *file
, char *const *argv
)
1117 dt_ident_t
*idp
= dt_idhash_lookup(dtp
->dt_macros
, "target");
1118 struct ps_prochandle
*P
= dt_proc_create(dtp
, file
, argv
);
1120 if (P
!= NULL
&& idp
!= NULL
&& idp
->di_id
== 0)
1121 idp
->di_id
= Pstatus(P
)->pr_pid
; /* $target = created pid */
1126 struct ps_prochandle
*
1127 dtrace_proc_grab(dtrace_hdl_t
*dtp
, pid_t pid
, int flags
)
1129 dt_ident_t
*idp
= dt_idhash_lookup(dtp
->dt_macros
, "target");
1130 struct ps_prochandle
*P
= dt_proc_grab(dtp
, pid
, flags
, 0);
1132 if (P
!= NULL
&& idp
!= NULL
&& idp
->di_id
== 0)
1133 idp
->di_id
= pid
; /* $target = grabbed pid */
1139 dtrace_proc_release(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1141 dt_proc_release(dtp
, P
);
1145 dtrace_proc_continue(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1147 dt_proc_continue(dtp
, P
);