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.
94 #define IS_SYS_EXEC(w) (w == SYS_execve)
95 #define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
98 dt_proc_bpcreate(dt_proc_t
*dpr
, uintptr_t addr
, dt_bkpt_f
*func
, void *data
)
100 struct ps_prochandle
*P
= dpr
->dpr_proc
;
103 assert(MUTEX_HELD(&dpr
->dpr_lock
));
105 if ((dbp
= dt_zalloc(dpr
->dpr_hdl
, sizeof (dt_bkpt_t
))) != NULL
) {
106 dbp
->dbp_func
= func
;
107 dbp
->dbp_data
= data
;
108 dbp
->dbp_addr
= addr
;
110 if (Psetbkpt(P
, dbp
->dbp_addr
, &dbp
->dbp_instr
) == 0)
111 dbp
->dbp_active
= B_TRUE
;
113 dt_list_append(&dpr
->dpr_bps
, dbp
);
120 dt_proc_bpdestroy(dt_proc_t
*dpr
, int delbkpts
)
122 int state
= Pstate(dpr
->dpr_proc
);
123 dt_bkpt_t
*dbp
, *nbp
;
125 assert(MUTEX_HELD(&dpr
->dpr_lock
));
127 for (dbp
= dt_list_next(&dpr
->dpr_bps
); dbp
!= NULL
; dbp
= nbp
) {
128 if (delbkpts
&& dbp
->dbp_active
&&
129 state
!= PS_LOST
&& state
!= PS_UNDEAD
) {
130 (void) Pdelbkpt(dpr
->dpr_proc
,
131 dbp
->dbp_addr
, dbp
->dbp_instr
);
133 nbp
= dt_list_next(dbp
);
134 dt_list_delete(&dpr
->dpr_bps
, dbp
);
135 dt_free(dpr
->dpr_hdl
, dbp
);
140 dt_proc_bpmatch(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
)
142 const lwpstatus_t
*psp
= &Pstatus(dpr
->dpr_proc
)->pr_lwp
;
145 assert(MUTEX_HELD(&dpr
->dpr_lock
));
147 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
148 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
149 if (psp
->pr_reg
[R_PC
] == dbp
->dbp_addr
)
154 dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
155 (int)dpr
->dpr_pid
, (ulong_t
)psp
->pr_reg
[R_PC
]);
159 dt_dprintf("pid %d: hit breakpoint at %lx (%lu)\n",
160 (int)dpr
->dpr_pid
, (ulong_t
)dbp
->dbp_addr
, ++dbp
->dbp_hits
);
162 dbp
->dbp_func(dtp
, dpr
, dbp
->dbp_data
);
163 (void) Pxecbkpt(dpr
->dpr_proc
, dbp
->dbp_instr
);
167 dt_proc_bpenable(dt_proc_t
*dpr
)
171 assert(MUTEX_HELD(&dpr
->dpr_lock
));
173 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
174 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
175 if (!dbp
->dbp_active
&& Psetbkpt(dpr
->dpr_proc
,
176 dbp
->dbp_addr
, &dbp
->dbp_instr
) == 0)
177 dbp
->dbp_active
= B_TRUE
;
180 dt_dprintf("breakpoints enabled\n");
184 dt_proc_bpdisable(dt_proc_t
*dpr
)
188 assert(MUTEX_HELD(&dpr
->dpr_lock
));
190 for (dbp
= dt_list_next(&dpr
->dpr_bps
);
191 dbp
!= NULL
; dbp
= dt_list_next(dbp
)) {
192 if (dbp
->dbp_active
&& Pdelbkpt(dpr
->dpr_proc
,
193 dbp
->dbp_addr
, dbp
->dbp_instr
) == 0)
194 dbp
->dbp_active
= B_FALSE
;
197 dt_dprintf("breakpoints disabled\n");
201 dt_proc_notify(dtrace_hdl_t
*dtp
, dt_proc_hash_t
*dph
, dt_proc_t
*dpr
,
204 dt_proc_notify_t
*dprn
= dt_alloc(dtp
, sizeof (dt_proc_notify_t
));
207 dt_dprintf("failed to allocate notification for %d %s\n",
208 (int)dpr
->dpr_pid
, msg
);
210 dprn
->dprn_dpr
= dpr
;
212 dprn
->dprn_errmsg
[0] = '\0';
214 (void) strlcpy(dprn
->dprn_errmsg
, msg
,
215 sizeof (dprn
->dprn_errmsg
));
217 (void) pthread_mutex_lock(&dph
->dph_lock
);
219 dprn
->dprn_next
= dph
->dph_notify
;
220 dph
->dph_notify
= dprn
;
222 (void) pthread_cond_broadcast(&dph
->dph_cv
);
223 (void) pthread_mutex_unlock(&dph
->dph_lock
);
228 * Check to see if the control thread was requested to stop when the victim
229 * process reached a particular event (why) rather than continuing the victim.
230 * If 'why' is set in the stop mask, we wait on dpr_cv for dt_proc_continue().
231 * If 'why' is not set, this function returns immediately and does nothing.
234 dt_proc_stop(dt_proc_t
*dpr
, uint8_t why
)
236 assert(MUTEX_HELD(&dpr
->dpr_lock
));
237 assert(why
!= DT_PROC_STOP_IDLE
);
239 if (dpr
->dpr_stop
& why
) {
240 dpr
->dpr_stop
|= DT_PROC_STOP_IDLE
;
241 dpr
->dpr_stop
&= ~why
;
243 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
246 * We disable breakpoints while stopped to preserve the
247 * integrity of the program text for both our own disassembly
248 * and that of the kernel.
250 dt_proc_bpdisable(dpr
);
252 while (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
)
253 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
255 dt_proc_bpenable(dpr
);
261 dt_proc_bpmain(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *fname
)
263 dt_dprintf("pid %d: breakpoint at %s()\n", (int)dpr
->dpr_pid
, fname
);
264 dt_proc_stop(dpr
, DT_PROC_STOP_MAIN
);
268 dt_proc_rdevent(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *evname
)
273 if ((err
= rd_event_getmsg(dpr
->dpr_rtld
, &rdm
)) != RD_OK
) {
274 dt_dprintf("pid %d: failed to get %s event message: %s\n",
275 (int)dpr
->dpr_pid
, evname
, rd_errstr(err
));
279 dt_dprintf("pid %d: rtld event %s type=%d state %d\n",
280 (int)dpr
->dpr_pid
, evname
, rdm
.type
, rdm
.u
.state
);
284 if (rdm
.u
.state
!= RD_CONSISTENT
)
287 Pupdate_syms(dpr
->dpr_proc
);
288 if (dt_pid_create_probes_module(dtp
, dpr
) != 0)
289 dt_proc_notify(dtp
, dtp
->dt_procs
, dpr
,
294 Pupdate_syms(dpr
->dpr_proc
);
295 dt_proc_stop(dpr
, DT_PROC_STOP_PREINIT
);
298 Pupdate_syms(dpr
->dpr_proc
);
299 dt_proc_stop(dpr
, DT_PROC_STOP_POSTINIT
);
305 dt_proc_rdwatch(dt_proc_t
*dpr
, rd_event_e event
, const char *evname
)
310 if ((err
= rd_event_addr(dpr
->dpr_rtld
, event
, &rdn
)) != RD_OK
) {
311 dt_dprintf("pid %d: failed to get event address for %s: %s\n",
312 (int)dpr
->dpr_pid
, evname
, rd_errstr(err
));
316 if (rdn
.type
!= RD_NOTIFY_BPT
) {
317 dt_dprintf("pid %d: event %s has unexpected type %d\n",
318 (int)dpr
->dpr_pid
, evname
, rdn
.type
);
322 (void) dt_proc_bpcreate(dpr
, rdn
.u
.bptaddr
,
323 (dt_bkpt_f
*)dt_proc_rdevent
, (void *)evname
);
327 * Common code for enabling events associated with the run-time linker after
328 * attaching to a process or after a victim process completes an exec(2).
331 dt_proc_attach(dt_proc_t
*dpr
, int exec
)
333 const pstatus_t
*psp
= Pstatus(dpr
->dpr_proc
);
337 assert(MUTEX_HELD(&dpr
->dpr_lock
));
340 if (psp
->pr_lwp
.pr_errno
!= 0)
341 return; /* exec failed: nothing needs to be done */
343 dt_proc_bpdestroy(dpr
, B_FALSE
);
344 Preset_maps(dpr
->dpr_proc
);
347 if ((dpr
->dpr_rtld
= Prd_agent(dpr
->dpr_proc
)) != NULL
&&
348 (err
= rd_event_enable(dpr
->dpr_rtld
, B_TRUE
)) == RD_OK
) {
349 dt_proc_rdwatch(dpr
, RD_PREINIT
, "RD_PREINIT");
350 dt_proc_rdwatch(dpr
, RD_POSTINIT
, "RD_POSTINIT");
351 dt_proc_rdwatch(dpr
, RD_DLACTIVITY
, "RD_DLACTIVITY");
353 dt_dprintf("pid %d: failed to enable rtld events: %s\n",
354 (int)dpr
->dpr_pid
, dpr
->dpr_rtld
? rd_errstr(err
) :
355 "rtld_db agent initialization failed");
358 Pupdate_maps(dpr
->dpr_proc
);
360 if (Pxlookup_by_name(dpr
->dpr_proc
, LM_ID_BASE
,
361 "a.out", "main", &sym
, NULL
) == 0) {
362 (void) dt_proc_bpcreate(dpr
, (uintptr_t)sym
.st_value
,
363 (dt_bkpt_f
*)dt_proc_bpmain
, "a.out`main");
365 dt_dprintf("pid %d: failed to find a.out`main: %s\n",
366 (int)dpr
->dpr_pid
, strerror(errno
));
371 * Wait for a stopped process to be set running again by some other debugger.
372 * This is typically not required by /proc-based debuggers, since the usual
373 * model is that one debugger controls one victim. But DTrace, as usual, has
374 * its own needs: the stop() action assumes that prun(1) or some other tool
375 * will be applied to resume the victim process. This could be solved by
376 * adding a PCWRUN directive to /proc, but that seems like overkill unless
377 * other debuggers end up needing this functionality, so we implement a cheap
378 * equivalent to PCWRUN using the set of existing kernel mechanisms.
380 * Our intent is really not just to wait for the victim to run, but rather to
381 * wait for it to run and then stop again for a reason other than the current
382 * PR_REQUESTED stop. Since PCWSTOP/Pstopstatus() can be applied repeatedly
383 * to a stopped process and will return the same result without affecting the
384 * victim, we can just perform these operations repeatedly until Pstate()
385 * changes, the representative LWP ID changes, or the stop timestamp advances.
386 * dt_proc_control() will then rediscover the new state and continue as usual.
387 * When the process is still stopped in the same exact state, we sleep for a
388 * brief interval before waiting again so as not to spin consuming CPU cycles.
391 dt_proc_waitrun(dt_proc_t
*dpr
)
393 struct ps_prochandle
*P
= dpr
->dpr_proc
;
394 const lwpstatus_t
*psp
= &Pstatus(P
)->pr_lwp
;
396 int krflag
= psp
->pr_flags
& (PR_KLC
| PR_RLC
);
397 timestruc_t tstamp
= psp
->pr_tstamp
;
398 lwpid_t lwpid
= psp
->pr_lwpid
;
400 const long wstop
= PCWSTOP
;
403 assert(MUTEX_HELD(&dpr
->dpr_lock
));
404 assert(psp
->pr_flags
& PR_STOPPED
);
405 assert(Pstate(P
) == PS_STOP
);
408 * While we are waiting for the victim to run, clear PR_KLC and PR_RLC
409 * so that if the libdtrace client is killed, the victim stays stopped.
410 * dt_proc_destroy() will also observe this and perform PRELEASE_HANG.
412 (void) Punsetflags(P
, krflag
);
415 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
417 while (!dpr
->dpr_quit
) {
418 if (write(pfd
, &wstop
, sizeof (wstop
)) == -1 && errno
== EINTR
)
419 continue; /* check dpr_quit and continue waiting */
421 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
422 (void) Pstopstatus(P
, PCNULL
, 0);
423 psp
= &Pstatus(P
)->pr_lwp
;
426 * If we've reached a new state, found a new representative, or
427 * the stop timestamp has changed, restore PR_KLC/PR_RLC to its
428 * original setting and then return with dpr_lock held.
430 if (Pstate(P
) != PS_STOP
|| psp
->pr_lwpid
!= lwpid
||
431 bcmp(&psp
->pr_tstamp
, &tstamp
, sizeof (tstamp
)) != 0) {
432 (void) Psetflags(P
, krflag
);
437 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
438 (void) poll(NULL
, 0, MILLISEC
/ 2);
441 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
444 typedef struct dt_proc_control_data
{
445 dtrace_hdl_t
*dpcd_hdl
; /* DTrace handle */
446 dt_proc_t
*dpcd_proc
; /* proccess to control */
447 } dt_proc_control_data_t
;
450 * Main loop for all victim process control threads. We initialize all the
451 * appropriate /proc control mechanisms, and then enter a loop waiting for
452 * the process to stop on an event or die. We process any events by calling
453 * appropriate subroutines, and exit when the victim dies or we lose control.
455 * The control thread synchronizes the use of dpr_proc with other libdtrace
456 * threads using dpr_lock. We hold the lock for all of our operations except
457 * waiting while the process is running: this is accomplished by writing a
458 * PCWSTOP directive directly to the underlying /proc/<pid>/ctl file. If the
459 * libdtrace client wishes to exit or abort our wait, SIGCANCEL can be used.
462 dt_proc_control(void *arg
)
464 dt_proc_control_data_t
*datap
= arg
;
465 dtrace_hdl_t
*dtp
= datap
->dpcd_hdl
;
466 dt_proc_t
*dpr
= datap
->dpcd_proc
;
467 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
468 struct ps_prochandle
*P
= dpr
->dpr_proc
;
471 int pid
= dpr
->dpr_pid
;
473 const long wstop
= PCWSTOP
;
474 int notify
= B_FALSE
;
477 * We disable the POSIX thread cancellation mechanism so that the
478 * client program using libdtrace can't accidentally cancel our thread.
479 * dt_proc_destroy() uses SIGCANCEL explicitly to simply poke us out
480 * of PCWSTOP with EINTR, at which point we will see dpr_quit and exit.
482 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
485 * Set up the corresponding process for tracing by libdtrace. We want
486 * to be able to catch breakpoints and efficiently single-step over
487 * them, and we need to enable librtld_db to watch libdl activity.
489 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
491 (void) Punsetflags(P
, PR_ASYNC
); /* require synchronous mode */
492 (void) Psetflags(P
, PR_BPTADJ
); /* always adjust eip on x86 */
493 (void) Punsetflags(P
, PR_FORK
); /* do not inherit on fork */
495 (void) Pfault(P
, FLTBPT
, B_TRUE
); /* always trace breakpoints */
496 (void) Pfault(P
, FLTTRACE
, B_TRUE
); /* always trace single-step */
499 * We must trace exit from exec() system calls so that if the exec is
500 * successful, we can reset our breakpoints and re-initialize libproc.
502 (void) Psysexit(P
, SYS_execve
, B_TRUE
);
505 * We must trace entry and exit for fork() system calls in order to
506 * disable our breakpoints temporarily during the fork. We do not set
507 * the PR_FORK flag, so if fork succeeds the child begins executing and
508 * does not inherit any other tracing behaviors or a control thread.
510 (void) Psysentry(P
, SYS_vfork
, B_TRUE
);
511 (void) Psysexit(P
, SYS_vfork
, B_TRUE
);
512 (void) Psysentry(P
, SYS_forksys
, B_TRUE
);
513 (void) Psysexit(P
, SYS_forksys
, B_TRUE
);
515 Psync(P
); /* enable all /proc changes */
516 dt_proc_attach(dpr
, B_FALSE
); /* enable rtld breakpoints */
519 * If PR_KLC is set, we created the process; otherwise we grabbed it.
520 * Check for an appropriate stop request and wait for dt_proc_continue.
522 if (Pstatus(P
)->pr_flags
& PR_KLC
)
523 dt_proc_stop(dpr
, DT_PROC_STOP_CREATE
);
525 dt_proc_stop(dpr
, DT_PROC_STOP_GRAB
);
527 if (Psetrun(P
, 0, 0) == -1) {
528 dt_dprintf("pid %d: failed to set running: %s\n",
529 (int)dpr
->dpr_pid
, strerror(errno
));
532 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
535 * Wait for the process corresponding to this control thread to stop,
536 * process the event, and then set it running again. We want to sleep
537 * with dpr_lock *unheld* so that other parts of libdtrace can use the
538 * ps_prochandle in the meantime (e.g. ustack()). To do this, we write
539 * a PCWSTOP directive directly to the underlying /proc/<pid>/ctl file.
540 * Once the process stops, we wake up, grab dpr_lock, and then call
541 * Pwait() (which will return immediately) and do our processing.
543 while (!dpr
->dpr_quit
) {
544 const lwpstatus_t
*psp
;
546 if (write(pfd
, &wstop
, sizeof (wstop
)) == -1 && errno
== EINTR
)
547 continue; /* check dpr_quit and continue waiting */
549 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
551 if (Pstopstatus(P
, PCNULL
, 0) == -1 && errno
== EINTR
) {
552 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
553 continue; /* check dpr_quit and continue waiting */
558 psp
= &Pstatus(P
)->pr_lwp
;
560 dt_dprintf("pid %d: proc stopped showing %d/%d\n",
561 pid
, psp
->pr_why
, psp
->pr_what
);
564 * If the process stops showing PR_REQUESTED, then the
565 * DTrace stop() action was applied to it or another
566 * debugging utility (e.g. pstop(1)) asked it to stop.
567 * In either case, the user's intention is for the
568 * process to remain stopped until another external
569 * mechanism (e.g. prun(1)) is applied. So instead of
570 * setting the process running ourself, we wait for
571 * someone else to do so. Once that happens, we return
572 * to our normal loop waiting for an event of interest.
574 if (psp
->pr_why
== PR_REQUESTED
) {
575 dt_proc_waitrun(dpr
);
576 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
581 * If the process stops showing one of the events that
582 * we are tracing, perform the appropriate response.
583 * Note that we ignore PR_SUSPENDED, PR_CHECKPOINT, and
584 * PR_JOBCONTROL by design: if one of these conditions
585 * occurs, we will fall through to Psetrun() but the
586 * process will remain stopped in the kernel by the
587 * corresponding mechanism (e.g. job control stop).
589 if (psp
->pr_why
== PR_FAULTED
&& psp
->pr_what
== FLTBPT
)
590 dt_proc_bpmatch(dtp
, dpr
);
591 else if (psp
->pr_why
== PR_SYSENTRY
&&
592 IS_SYS_FORK(psp
->pr_what
))
593 dt_proc_bpdisable(dpr
);
594 else if (psp
->pr_why
== PR_SYSEXIT
&&
595 IS_SYS_FORK(psp
->pr_what
))
596 dt_proc_bpenable(dpr
);
597 else if (psp
->pr_why
== PR_SYSEXIT
&&
598 IS_SYS_EXEC(psp
->pr_what
))
599 dt_proc_attach(dpr
, B_TRUE
);
606 dt_dprintf("pid %d: proc lost: %s\n",
607 pid
, strerror(errno
));
609 dpr
->dpr_quit
= B_TRUE
;
614 dt_dprintf("pid %d: proc died\n", pid
);
615 dpr
->dpr_quit
= B_TRUE
;
620 if (Pstate(P
) != PS_UNDEAD
&& Psetrun(P
, 0, 0) == -1) {
621 dt_dprintf("pid %d: failed to set running: %s\n",
622 (int)dpr
->dpr_pid
, strerror(errno
));
625 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
629 * If the control thread detected PS_UNDEAD or PS_LOST, then enqueue
630 * the dt_proc_t structure on the dt_proc_hash_t notification list.
633 dt_proc_notify(dtp
, dph
, dpr
, NULL
);
636 * Destroy and remove any remaining breakpoints, set dpr_done and clear
637 * dpr_tid to indicate the control thread has exited, and notify any
638 * waiting thread in dt_proc_destroy() that we have succesfully exited.
640 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
642 dt_proc_bpdestroy(dpr
, B_TRUE
);
643 dpr
->dpr_done
= B_TRUE
;
646 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
647 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
653 static struct ps_prochandle
*
654 dt_proc_error(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, const char *format
, ...)
658 va_start(ap
, format
);
659 dt_set_errmsg(dtp
, NULL
, NULL
, NULL
, 0, format
, ap
);
662 if (dpr
->dpr_proc
!= NULL
)
663 Prelease(dpr
->dpr_proc
, 0);
666 (void) dt_set_errno(dtp
, EDT_COMPILER
);
671 dt_proc_lookup(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
, int remove
)
673 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
674 pid_t pid
= Pstatus(P
)->pr_pid
;
675 dt_proc_t
*dpr
, **dpp
= &dph
->dph_hash
[pid
& (dph
->dph_hashlen
- 1)];
677 for (dpr
= *dpp
; dpr
!= NULL
; dpr
= dpr
->dpr_hash
) {
678 if (dpr
->dpr_pid
== pid
)
681 dpp
= &dpr
->dpr_hash
;
685 assert(dpr
->dpr_proc
== P
);
688 *dpp
= dpr
->dpr_hash
; /* remove from pid hash chain */
694 dt_proc_destroy(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
696 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
697 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
698 dt_proc_notify_t
*npr
, **npp
;
704 * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
705 * an external debugger and we were waiting in dt_proc_waitrun().
706 * Leave the process in this condition using PRELEASE_HANG.
708 if (!(Pstatus(dpr
->dpr_proc
)->pr_flags
& (PR_KLC
| PR_RLC
))) {
709 dt_dprintf("abandoning pid %d\n", (int)dpr
->dpr_pid
);
710 rflag
= PRELEASE_HANG
;
711 } else if (Pstatus(dpr
->dpr_proc
)->pr_flags
& PR_KLC
) {
712 dt_dprintf("killing pid %d\n", (int)dpr
->dpr_pid
);
713 rflag
= PRELEASE_KILL
; /* apply kill-on-last-close */
715 dt_dprintf("releasing pid %d\n", (int)dpr
->dpr_pid
);
716 rflag
= 0; /* apply run-on-last-close */
721 * Set the dpr_quit flag to tell the daemon thread to exit. We
722 * send it a SIGCANCEL to poke it out of PCWSTOP or any other
723 * long-term /proc system call. Our daemon threads have POSIX
724 * cancellation disabled, so EINTR will be the only effect. We
725 * then wait for dpr_done to indicate the thread has exited.
727 * We can't use pthread_kill() to send SIGCANCEL because the
728 * interface forbids it and we can't use pthread_cancel()
729 * because with cancellation disabled it won't actually
730 * send SIGCANCEL to the target thread, so we use _lwp_kill()
731 * to do the job. This is all built on evil knowledge of
732 * the details of the cancellation mechanism in libc.
734 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
735 dpr
->dpr_quit
= B_TRUE
;
736 (void) _lwp_kill(dpr
->dpr_tid
, SIGCANCEL
);
739 * If the process is currently idling in dt_proc_stop(), re-
740 * enable breakpoints and poke it into running again.
742 if (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
) {
743 dt_proc_bpenable(dpr
);
744 dpr
->dpr_stop
&= ~DT_PROC_STOP_IDLE
;
745 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
748 while (!dpr
->dpr_done
)
749 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
751 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
755 * Before we free the process structure, remove this dt_proc_t from the
756 * lookup hash, and then walk the dt_proc_hash_t's notification list
757 * and remove this dt_proc_t if it is enqueued.
759 (void) pthread_mutex_lock(&dph
->dph_lock
);
760 (void) dt_proc_lookup(dtp
, P
, B_TRUE
);
761 npp
= &dph
->dph_notify
;
763 while ((npr
= *npp
) != NULL
) {
764 if (npr
->dprn_dpr
== dpr
) {
765 *npp
= npr
->dprn_next
;
768 npp
= &npr
->dprn_next
;
772 (void) pthread_mutex_unlock(&dph
->dph_lock
);
775 * Remove the dt_proc_list from the LRU list, release the underlying
776 * libproc handle, and free our dt_proc_t data structure.
778 if (dpr
->dpr_cacheable
) {
779 assert(dph
->dph_lrucnt
!= 0);
783 dt_list_delete(&dph
->dph_lrulist
, dpr
);
784 Prelease(dpr
->dpr_proc
, rflag
);
789 dt_proc_create_thread(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
, uint_t stop
)
791 dt_proc_control_data_t data
;
796 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
797 dpr
->dpr_stop
|= stop
; /* set bit for initial rendezvous */
799 (void) pthread_attr_init(&a
);
800 (void) pthread_attr_setdetachstate(&a
, PTHREAD_CREATE_DETACHED
);
802 (void) sigfillset(&nset
);
803 (void) sigdelset(&nset
, SIGABRT
); /* unblocked for assert() */
804 (void) sigdelset(&nset
, SIGCANCEL
); /* see dt_proc_destroy() */
807 data
.dpcd_proc
= dpr
;
809 (void) pthread_sigmask(SIG_SETMASK
, &nset
, &oset
);
810 err
= pthread_create(&dpr
->dpr_tid
, &a
, dt_proc_control
, &data
);
811 (void) pthread_sigmask(SIG_SETMASK
, &oset
, NULL
);
814 * If the control thread was created, then wait on dpr_cv for either
815 * dpr_done to be set (the victim died or the control thread failed)
816 * or DT_PROC_STOP_IDLE to be set, indicating that the victim is now
817 * stopped by /proc and the control thread is at the rendezvous event.
818 * On success, we return with the process and control thread stopped:
819 * the caller can then apply dt_proc_continue() to resume both.
822 while (!dpr
->dpr_done
&& !(dpr
->dpr_stop
& DT_PROC_STOP_IDLE
))
823 (void) pthread_cond_wait(&dpr
->dpr_cv
, &dpr
->dpr_lock
);
826 * If dpr_done is set, the control thread aborted before it
827 * reached the rendezvous event. This is either due to PS_LOST
828 * or PS_UNDEAD (i.e. the process died). We try to provide a
829 * small amount of useful information to help figure it out.
832 const psinfo_t
*prp
= Ppsinfo(dpr
->dpr_proc
);
833 int stat
= prp
? prp
->pr_wstat
: 0;
834 int pid
= dpr
->dpr_pid
;
836 if (Pstate(dpr
->dpr_proc
) == PS_LOST
) {
837 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
838 "failed to control pid %d: process exec'd "
839 "set-id or unobservable program\n", pid
);
840 } else if (WIFSIGNALED(stat
)) {
841 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
842 "failed to control pid %d: process died "
843 "from signal %d\n", pid
, WTERMSIG(stat
));
845 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
846 "failed to control pid %d: process exited "
847 "with status %d\n", pid
, WEXITSTATUS(stat
));
850 err
= ESRCH
; /* cause grab() or create() to fail */
853 (void) dt_proc_error(dpr
->dpr_hdl
, dpr
,
854 "failed to create control thread for process-id %d: %s\n",
855 (int)dpr
->dpr_pid
, strerror(err
));
858 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
859 (void) pthread_attr_destroy(&a
);
864 struct ps_prochandle
*
865 dt_proc_create(dtrace_hdl_t
*dtp
, const char *file
, char *const *argv
)
867 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
871 if ((dpr
= dt_zalloc(dtp
, sizeof (dt_proc_t
))) == NULL
)
872 return (NULL
); /* errno is set for us */
874 (void) pthread_mutex_init(&dpr
->dpr_lock
, NULL
);
875 (void) pthread_cond_init(&dpr
->dpr_cv
, NULL
);
877 dpr
->dpr_proc
= Pxcreate(file
, argv
, dtp
->dt_proc_env
, &err
, NULL
, 0);
878 if (dpr
->dpr_proc
== NULL
) {
879 return (dt_proc_error(dtp
, dpr
,
880 "failed to execute %s: %s\n", file
, Pcreate_error(err
)));
884 dpr
->dpr_pid
= Pstatus(dpr
->dpr_proc
)->pr_pid
;
886 (void) Punsetflags(dpr
->dpr_proc
, PR_RLC
);
887 (void) Psetflags(dpr
->dpr_proc
, PR_KLC
);
889 if (dt_proc_create_thread(dtp
, dpr
, dtp
->dt_prcmode
) != 0)
890 return (NULL
); /* dt_proc_error() has been called for us */
892 dpr
->dpr_hash
= dph
->dph_hash
[dpr
->dpr_pid
& (dph
->dph_hashlen
- 1)];
893 dph
->dph_hash
[dpr
->dpr_pid
& (dph
->dph_hashlen
- 1)] = dpr
;
894 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
896 dt_dprintf("created pid %d\n", (int)dpr
->dpr_pid
);
899 return (dpr
->dpr_proc
);
902 struct ps_prochandle
*
903 dt_proc_grab(dtrace_hdl_t
*dtp
, pid_t pid
, int flags
, int nomonitor
)
905 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
906 uint_t h
= pid
& (dph
->dph_hashlen
- 1);
907 dt_proc_t
*dpr
, *opr
;
911 * Search the hash table for the pid. If it is already grabbed or
912 * created, move the handle to the front of the lrulist, increment
913 * the reference count, and return the existing ps_prochandle.
915 for (dpr
= dph
->dph_hash
[h
]; dpr
!= NULL
; dpr
= dpr
->dpr_hash
) {
916 if (dpr
->dpr_pid
== pid
&& !dpr
->dpr_stale
) {
918 * If the cached handle was opened read-only and
919 * this request is for a writeable handle, mark
920 * the cached handle as stale and open a new handle.
921 * Since it's stale, unmark it as cacheable.
923 if (dpr
->dpr_rdonly
&& !(flags
& PGRAB_RDONLY
)) {
924 dt_dprintf("upgrading pid %d\n", (int)pid
);
925 dpr
->dpr_stale
= B_TRUE
;
926 dpr
->dpr_cacheable
= B_FALSE
;
931 dt_dprintf("grabbed pid %d (cached)\n", (int)pid
);
932 dt_list_delete(&dph
->dph_lrulist
, dpr
);
933 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
935 return (dpr
->dpr_proc
);
939 if ((dpr
= dt_zalloc(dtp
, sizeof (dt_proc_t
))) == NULL
)
940 return (NULL
); /* errno is set for us */
942 (void) pthread_mutex_init(&dpr
->dpr_lock
, NULL
);
943 (void) pthread_cond_init(&dpr
->dpr_cv
, NULL
);
945 if ((dpr
->dpr_proc
= Pgrab(pid
, flags
, &err
)) == NULL
) {
946 return (dt_proc_error(dtp
, dpr
,
947 "failed to grab pid %d: %s\n", (int)pid
, Pgrab_error(err
)));
953 (void) Punsetflags(dpr
->dpr_proc
, PR_KLC
);
954 (void) Psetflags(dpr
->dpr_proc
, PR_RLC
);
957 * If we are attempting to grab the process without a monitor
958 * thread, then mark the process cacheable only if it's being
959 * grabbed read-only. If we're currently caching more process
960 * handles than dph_lrulim permits, attempt to find the
961 * least-recently-used handle that is currently unreferenced and
962 * release it from the cache. Otherwise we are grabbing the process
963 * for control: create a control thread for this process and store
964 * its ID in dpr->dpr_tid.
966 if (nomonitor
|| (flags
& PGRAB_RDONLY
)) {
967 if (dph
->dph_lrucnt
>= dph
->dph_lrulim
) {
968 for (opr
= dt_list_prev(&dph
->dph_lrulist
);
969 opr
!= NULL
; opr
= dt_list_prev(opr
)) {
970 if (opr
->dpr_cacheable
&& opr
->dpr_refs
== 0) {
971 dt_proc_destroy(dtp
, opr
->dpr_proc
);
977 if (flags
& PGRAB_RDONLY
) {
978 dpr
->dpr_cacheable
= B_TRUE
;
979 dpr
->dpr_rdonly
= B_TRUE
;
983 } else if (dt_proc_create_thread(dtp
, dpr
, DT_PROC_STOP_GRAB
) != 0)
984 return (NULL
); /* dt_proc_error() has been called for us */
986 dpr
->dpr_hash
= dph
->dph_hash
[h
];
987 dph
->dph_hash
[h
] = dpr
;
988 dt_list_prepend(&dph
->dph_lrulist
, dpr
);
990 dt_dprintf("grabbed pid %d\n", (int)pid
);
993 return (dpr
->dpr_proc
);
997 dt_proc_release(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
999 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1000 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
1002 assert(dpr
!= NULL
);
1003 assert(dpr
->dpr_refs
!= 0);
1005 if (--dpr
->dpr_refs
== 0 &&
1006 (!dpr
->dpr_cacheable
|| dph
->dph_lrucnt
> dph
->dph_lrulim
))
1007 dt_proc_destroy(dtp
, P
);
1011 dt_proc_continue(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1013 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1015 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
1017 if (dpr
->dpr_stop
& DT_PROC_STOP_IDLE
) {
1018 dpr
->dpr_stop
&= ~DT_PROC_STOP_IDLE
;
1019 (void) pthread_cond_broadcast(&dpr
->dpr_cv
);
1022 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
1026 dt_proc_lock(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1028 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1029 int err
= pthread_mutex_lock(&dpr
->dpr_lock
);
1030 assert(err
== 0); /* check for recursion */
1034 dt_proc_unlock(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1036 dt_proc_t
*dpr
= dt_proc_lookup(dtp
, P
, B_FALSE
);
1037 int err
= pthread_mutex_unlock(&dpr
->dpr_lock
);
1038 assert(err
== 0); /* check for unheld lock */
1042 dt_proc_init(dtrace_hdl_t
*dtp
)
1044 extern char **environ
;
1045 static char *envdef
[] = {
1046 "LD_NOLAZYLOAD=1", /* linker lazy loading hides funcs */
1052 if ((dtp
->dt_procs
= dt_zalloc(dtp
, sizeof (dt_proc_hash_t
) +
1053 sizeof (dt_proc_t
*) * _dtrace_pidbuckets
- 1)) == NULL
)
1056 (void) pthread_mutex_init(&dtp
->dt_procs
->dph_lock
, NULL
);
1057 (void) pthread_cond_init(&dtp
->dt_procs
->dph_cv
, NULL
);
1059 dtp
->dt_procs
->dph_hashlen
= _dtrace_pidbuckets
;
1060 dtp
->dt_procs
->dph_lrulim
= _dtrace_pidlrulim
;
1064 * Count how big our environment needs to be.
1066 for (i
= 1, p
= environ
; *p
!= NULL
; i
++, p
++)
1068 for (p
= envdef
; *p
!= NULL
; i
++, p
++)
1071 if ((dtp
->dt_proc_env
= dt_zalloc(dtp
, sizeof (char *) * i
)) == NULL
)
1074 for (i
= 0, p
= environ
; *p
!= NULL
; i
++, p
++) {
1075 if ((dtp
->dt_proc_env
[i
] = strdup(*p
)) == NULL
)
1078 for (p
= envdef
; *p
!= NULL
; i
++, p
++) {
1079 if ((dtp
->dt_proc_env
[i
] = strdup(*p
)) == NULL
)
1087 dt_free(dtp
, dtp
->dt_proc_env
[i
]);
1089 dt_free(dtp
, dtp
->dt_proc_env
);
1090 dtp
->dt_proc_env
= NULL
;
1094 dt_proc_fini(dtrace_hdl_t
*dtp
)
1096 dt_proc_hash_t
*dph
= dtp
->dt_procs
;
1100 while ((dpr
= dt_list_next(&dph
->dph_lrulist
)) != NULL
)
1101 dt_proc_destroy(dtp
, dpr
->dpr_proc
);
1103 dtp
->dt_procs
= NULL
;
1106 for (p
= dtp
->dt_proc_env
; *p
!= NULL
; p
++)
1109 dt_free(dtp
, dtp
->dt_proc_env
);
1110 dtp
->dt_proc_env
= NULL
;
1113 struct ps_prochandle
*
1114 dtrace_proc_create(dtrace_hdl_t
*dtp
, const char *file
, char *const *argv
)
1116 dt_ident_t
*idp
= dt_idhash_lookup(dtp
->dt_macros
, "target");
1117 struct ps_prochandle
*P
= dt_proc_create(dtp
, file
, argv
);
1119 if (P
!= NULL
&& idp
!= NULL
&& idp
->di_id
== 0)
1120 idp
->di_id
= Pstatus(P
)->pr_pid
; /* $target = created pid */
1125 struct ps_prochandle
*
1126 dtrace_proc_grab(dtrace_hdl_t
*dtp
, pid_t pid
, int flags
)
1128 dt_ident_t
*idp
= dt_idhash_lookup(dtp
->dt_macros
, "target");
1129 struct ps_prochandle
*P
= dt_proc_grab(dtp
, pid
, flags
, 0);
1131 if (P
!= NULL
&& idp
!= NULL
&& idp
->di_id
== 0)
1132 idp
->di_id
= pid
; /* $target = grabbed pid */
1138 dtrace_proc_release(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1140 dt_proc_release(dtp
, P
);
1144 dtrace_proc_continue(dtrace_hdl_t
*dtp
, struct ps_prochandle
*P
)
1146 dt_proc_continue(dtp
, P
);