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.
27 * Copyright 2018 Joyent, Inc.
28 * Copyright (c) 2014 by Delphix. All rights reserved.
34 * The user process target is invoked when the -u or -p command-line options
35 * are used, or when an ELF executable file or ELF core file is specified on
36 * the command-line. This target is also selected by default when no target
37 * options are present. In this case, it defaults the executable name to
38 * "a.out". If no process or core file is currently attached, the target
39 * functions as a kind of virtual /dev/zero (in accordance with adb(1)
40 * semantics); reads from the virtual address space return zeroes and writes
41 * fail silently. The proc target itself is designed as a wrapper around the
42 * services provided by libproc.so: t->t_pshandle is set to the struct
43 * ps_prochandle pointer returned as a handle by libproc. The target also
44 * opens the executable file itself using the MDB GElf services, for
45 * interpreting the .symtab and .dynsym if no libproc handle has been
46 * initialized, and for handling i/o to and from the object file. Currently,
47 * the only ISA-dependent portions of the proc target are the $r and ::fpregs
48 * dcmds, the callbacks for t_next() and t_step_out(), and the list of named
49 * registers; these are linked in from the proc_isadep.c file for each ISA and
50 * called from the common code in this file.
52 * The user process target implements complete user process control using the
53 * facilities provided by libproc.so. The MDB execution control model and
54 * an overview of software event management is described in mdb_target.c. The
55 * proc target implements breakpoints by replacing the instruction of interest
56 * with a trap instruction, and then restoring the original instruction to step
57 * over the breakpoint. The idea of replacing program text with instructions
58 * that transfer control to the debugger dates back as far as 1951 [1]. When
59 * the target stops, we replace each breakpoint with the original instruction
60 * as part of the disarm operation. This means that no special processing is
61 * required for t_vread() because the instrumented instructions will never be
62 * seen by the debugger once the target stops. Some debuggers have improved
63 * start/stop performance by leaving breakpoint traps in place and then
64 * handling a read from a breakpoint address as a special case. Although this
65 * improves efficiency for a source-level debugger, it runs somewhat contrary
66 * to the philosophy of the low-level debugger. Since we remove the
67 * instructions, users can apply other external debugging tools to the process
68 * once it has stopped (e.g. the proc(1) tools) and not be misled by MDB
69 * instrumentation. The tracing of faults, signals, system calls, and
70 * watchpoints and general process inspection is implemented directly using
71 * the mechanisms provided by /proc, as described originally in [2] and [3].
75 * [1] S. Gill, "The Diagnosis Of Mistakes In Programmes on the EDSAC",
76 * Proceedings of the Royal Society Series A Mathematical and Physical
77 * Sciences, Cambridge University Press, 206(1087), May 1951, pp. 538-554.
79 * [2] T.J. Killian, "Processes as Files", Proceedings of the USENIX Association
80 * Summer Conference, Salt Lake City, June 1984, pp. 203-207.
82 * [3] Roger Faulkner and Ron Gomes, "The Process File System and Process
83 * Model in UNIX System V", Proceedings of the USENIX Association
84 * Winter Conference, Dallas, January 1991, pp. 243-252.
87 #include <mdb/mdb_proc.h>
88 #include <mdb/mdb_disasm.h>
89 #include <mdb/mdb_signal.h>
90 #include <mdb/mdb_string.h>
91 #include <mdb/mdb_module.h>
92 #include <mdb/mdb_debug.h>
93 #include <mdb/mdb_conf.h>
94 #include <mdb/mdb_err.h>
95 #include <mdb/mdb_types.h>
98 #include <sys/utsname.h>
100 #include <sys/stat.h>
103 #include <stdio_ext.h>
107 #define PC_FAKE -1UL /* illegal pc value unequal 0 */
108 #define PANIC_BUFSIZE 1024
110 static const char PT_EXEC_PATH
[] = "a.out"; /* Default executable */
111 static const char PT_CORE_PATH
[] = "core"; /* Default core file */
113 static const pt_ptl_ops_t proc_lwp_ops
;
114 static const pt_ptl_ops_t proc_tdb_ops
;
115 static const mdb_se_ops_t proc_brkpt_ops
;
116 static const mdb_se_ops_t proc_wapt_ops
;
118 static int pt_setrun(mdb_tgt_t
*, mdb_tgt_status_t
*, int);
119 static void pt_activate_common(mdb_tgt_t
*);
120 static mdb_tgt_vespec_f pt_ignore_sig
;
121 static mdb_tgt_se_f pt_fork
;
122 static mdb_tgt_se_f pt_exec
;
124 static int pt_lookup_by_name_thr(mdb_tgt_t
*, const char *,
125 const char *, GElf_Sym
*, mdb_syminfo_t
*, mdb_tgt_tid_t
);
126 static int tlsbase(mdb_tgt_t
*, mdb_tgt_tid_t
, Lmid_t
, const char *,
130 * When debugging postmortem, we don't resolve names as we may very well not
131 * be on a system on which those names resolve.
133 #define PT_LIBPROC_RESOLVE(P) \
134 (!(mdb.m_flags & MDB_FL_LMRAW) && Pstate(P) != PS_DEAD)
137 * The Perror_printf() function interposes on the default, empty libproc
138 * definition. It will be called to report additional information on complex
139 * errors, such as a corrupt core file. We just pass the args to vwarn.
143 Perror_printf(struct ps_prochandle
*P
, const char *format
, ...)
147 va_start(alist
, format
);
148 vwarn(format
, alist
);
153 * Open the specified i/o backend as the a.out executable file, and attempt to
154 * load its standard and dynamic symbol tables. Note that if mdb_gelf_create
155 * succeeds, io is assigned to p_fio and is automatically held by gelf_create.
157 static mdb_gelf_file_t
*
158 pt_open_aout(mdb_tgt_t
*t
, mdb_io_t
*io
)
160 pt_data_t
*pt
= t
->t_data
;
163 if ((pt
->p_file
= mdb_gelf_create(io
, ET_NONE
, GF_FILE
)) == NULL
)
166 pt
->p_symtab
= mdb_gelf_symtab_create_file(pt
->p_file
,
167 SHT_SYMTAB
, MDB_TGT_SYMTAB
);
168 pt
->p_dynsym
= mdb_gelf_symtab_create_file(pt
->p_file
,
169 SHT_DYNSYM
, MDB_TGT_DYNSYM
);
172 * If we've got an _start symbol with a zero size, prime the private
173 * symbol table with a copy of _start with its size set to the distance
174 * between _mcount and _start. We do this because DevPro has shipped
175 * the Intel crt1.o without proper .size directives for years, which
176 * precludes proper identification of _start in stack traces.
178 if (mdb_gelf_symtab_lookup_by_name(pt
->p_dynsym
, "_start", &s1
,
179 NULL
) == 0 && s1
.st_size
== 0 &&
180 GELF_ST_TYPE(s1
.st_info
) == STT_FUNC
) {
181 if (mdb_gelf_symtab_lookup_by_name(pt
->p_dynsym
, "_mcount",
182 &s2
, NULL
) == 0 && GELF_ST_TYPE(s2
.st_info
) == STT_FUNC
) {
183 s1
.st_size
= s2
.st_value
- s1
.st_value
;
184 mdb_gelf_symtab_insert(mdb
.m_prsym
, "_start", &s1
);
193 * Destroy the symbol tables and GElf file object associated with p_fio. Note
194 * that we do not need to explicitly free p_fio: its reference count is
195 * automatically decremented by mdb_gelf_destroy, which will free it if needed.
198 pt_close_aout(mdb_tgt_t
*t
)
200 pt_data_t
*pt
= t
->t_data
;
202 if (pt
->p_symtab
!= NULL
) {
203 mdb_gelf_symtab_destroy(pt
->p_symtab
);
207 if (pt
->p_dynsym
!= NULL
) {
208 mdb_gelf_symtab_destroy(pt
->p_dynsym
);
212 if (pt
->p_file
!= NULL
) {
213 mdb_gelf_destroy(pt
->p_file
);
217 mdb_gelf_symtab_delete(mdb
.m_prsym
, "_start", NULL
);
221 typedef struct tdb_mapping
{
222 const char *tm_thr_lib
;
223 const char *tm_db_dir
;
224 const char *tm_db_name
;
227 static const tdb_mapping_t tdb_map
[] = {
228 { "/lwp/amd64/libthread.so", "/usr/lib/lwp/", "libthread_db.so" },
229 { "/lwp/sparcv9/libthread.so", "/usr/lib/lwp/", "libthread_db.so" },
230 { "/lwp/libthread.so", "/usr/lib/lwp/", "libthread_db.so" },
231 { "/libthread.so", "/lib/", "libthread_db.so" },
232 { "/libc_hwcap", "/lib/", "libc_db.so" },
233 { "/libc.so", "/lib/", "libc_db.so" }
237 * Pobject_iter callback that we use to search for the presence of libthread in
238 * order to load the corresponding libthread_db support. We derive the
239 * libthread_db path dynamically based on the libthread path. If libthread is
240 * found, this function returns 1 (and thus Pobject_iter aborts and returns 1)
241 * regardless of whether it was successful in loading the libthread_db support.
242 * If we iterate over all objects and no libthread is found, 0 is returned.
243 * Since libthread_db support was then merged into libc_db, we load either
244 * libc_db or libthread_db, depending on which library we see first.
248 thr_check(mdb_tgt_t
*t
, const prmap_t
*pmp
, const char *name
)
250 pt_data_t
*pt
= t
->t_data
;
251 const mdb_tdb_ops_t
*ops
;
254 char path
[MAXPATHLEN
];
259 return (0); /* no rtld_db object name; keep going */
261 for (libn
= 0; libn
< sizeof (tdb_map
) / sizeof (tdb_map
[0]); libn
++) {
262 if ((p
= strstr(name
, tdb_map
[libn
].tm_thr_lib
)) != NULL
)
267 return (0); /* no match; keep going */
270 (void) strlcat(path
, mdb
.m_root
, sizeof (path
));
271 (void) strlcat(path
, tdb_map
[libn
].tm_db_dir
, sizeof (path
));
273 (void) strlcat(path
, "64/", sizeof (path
));
275 (void) strlcat(path
, tdb_map
[libn
].tm_db_name
, sizeof (path
));
277 /* Append the trailing library version number. */
278 (void) strlcat(path
, strrchr(name
, '.'), sizeof (path
));
280 if ((ops
= mdb_tdb_load(path
)) == NULL
) {
281 if (libn
!= 0 || errno
!= ENOENT
)
282 warn("failed to load %s", path
);
286 if (ops
== pt
->p_tdb_ops
)
287 return (1); /* no changes needed */
291 pt
->p_ptl_ops
= &proc_tdb_ops
;
292 pt
->p_ptl_hdl
= NULL
;
294 if (PTL_CTOR(t
) == -1) {
295 warn("failed to initialize %s", path
);
299 mdb_dprintf(MDB_DBG_TGT
, "loaded %s for debugging %s\n", path
, name
);
300 (void) mdb_tgt_status(t
, &t
->t_status
);
304 pt
->p_tdb_ops
= NULL
;
305 pt
->p_ptl_ops
= &proc_lwp_ops
;
306 pt
->p_ptl_hdl
= NULL
;
308 if (libn
!= 0 || errno
!= ENOENT
) {
309 warn("warning: debugger will only be able to "
310 "examine raw LWPs\n");
313 (void) mdb_tgt_status(t
, &t
->t_status
);
318 * Whenever the link map is consistent following an add or delete event, we ask
319 * libproc to update its mappings, check to see if we need to load libthread_db,
320 * and then update breakpoints which have been mapped or unmapped.
324 pt_rtld_event(mdb_tgt_t
*t
, int vid
, void *private)
326 struct ps_prochandle
*P
= t
->t_pshandle
;
327 pt_data_t
*pt
= t
->t_data
;
331 if (rd_event_getmsg(pt
->p_rtld
, &rdm
) == RD_OK
) {
333 mdb_dprintf(MDB_DBG_TGT
, "rtld event type 0x%x state 0x%x\n",
334 rdm
.type
, rdm
.u
.state
);
336 if (rdm
.type
== RD_DLACTIVITY
&& rdm
.u
.state
== RD_CONSISTENT
) {
337 mdb_sespec_t
*sep
, *nsep
= mdb_list_next(&t
->t_active
);
342 if (Pobject_iter(P
, (proc_map_f
*)thr_check
, t
) == 0 &&
343 pt
->p_ptl_ops
!= &proc_lwp_ops
) {
344 mdb_dprintf(MDB_DBG_TGT
, "unloading thread_db "
345 "support after dlclose\n");
347 pt
->p_tdb_ops
= NULL
;
348 pt
->p_ptl_ops
= &proc_lwp_ops
;
349 pt
->p_ptl_hdl
= NULL
;
350 (void) mdb_tgt_status(t
, &t
->t_status
);
353 for (sep
= nsep
; sep
!= NULL
; sep
= nsep
) {
354 nsep
= mdb_list_next(sep
);
357 if (sep
->se_ops
== &proc_brkpt_ops
&&
358 Paddr_to_map(P
, ptb
->ptb_addr
) == NULL
)
359 mdb_tgt_sespec_idle_one(t
, sep
,
363 if (!mdb_tgt_sespec_activate_all(t
) &&
364 (mdb
.m_flags
& MDB_FL_BPTNOSYMSTOP
) &&
365 pt
->p_rtld_finished
) {
367 * We weren't able to activate the breakpoints.
368 * If so requested, we'll return without
369 * calling continue, thus throwing the user into
375 if (pt
->p_rdstate
== PT_RD_ADD
)
376 pt
->p_rdstate
= PT_RD_CONSIST
;
379 if (rdm
.type
== RD_PREINIT
)
380 (void) mdb_tgt_sespec_activate_all(t
);
382 if (rdm
.type
== RD_POSTINIT
) {
383 pt
->p_rtld_finished
= TRUE
;
384 if (!mdb_tgt_sespec_activate_all(t
) &&
385 (mdb
.m_flags
& MDB_FL_BPTNOSYMSTOP
)) {
387 * Now that rtld has been initialized, we
388 * should be able to initialize all deferred
389 * breakpoints. If we can't, don't let the
396 if (rdm
.type
== RD_DLACTIVITY
&& rdm
.u
.state
== RD_ADD
&&
398 pt
->p_rdstate
= MAX(pt
->p_rdstate
, PT_RD_ADD
);
402 (void) mdb_tgt_continue(t
, NULL
);
406 pt_post_attach(mdb_tgt_t
*t
)
408 struct ps_prochandle
*P
= t
->t_pshandle
;
409 const lwpstatus_t
*psp
= &Pstatus(P
)->pr_lwp
;
410 pt_data_t
*pt
= t
->t_data
;
411 int hflag
= MDB_TGT_SPEC_HIDDEN
;
413 mdb_dprintf(MDB_DBG_TGT
, "attach pr_flags=0x%x pr_why=%d pr_what=%d\n",
414 psp
->pr_flags
, psp
->pr_why
, psp
->pr_what
);
417 * When we grab a process, the initial setting of p_rtld_finished
418 * should be false if the process was just created by exec; otherwise
419 * we permit unscoped references to resolve because we do not know how
420 * far the process has proceeded through linker initialization.
422 if ((psp
->pr_flags
& PR_ISTOP
) && psp
->pr_why
== PR_SYSEXIT
&&
423 psp
->pr_errno
== 0 && psp
->pr_what
== SYS_execve
) {
424 if (mdb
.m_target
== NULL
) {
425 warn("target performed exec of %s\n",
426 IOP_NAME(pt
->p_fio
));
428 pt
->p_rtld_finished
= FALSE
;
430 pt
->p_rtld_finished
= TRUE
;
433 * When we grab a process, if it is stopped by job control and part of
434 * the same session (i.e. same controlling tty), set MDB_FL_JOBCTL so
435 * we will know to bring it to the foreground when we continue it.
437 if (mdb
.m_term
!= NULL
&& (psp
->pr_flags
& PR_STOPPED
) &&
438 psp
->pr_why
== PR_JOBCONTROL
&& getsid(0) == Pstatus(P
)->pr_sid
)
439 mdb
.m_flags
|= MDB_FL_JOBCTL
;
442 * When we grab control of a live process, set F_RDWR so that the
443 * target layer permits writes to the target's address space.
445 t
->t_flags
|= MDB_TGT_F_RDWR
;
447 (void) Pfault(P
, FLTBPT
, TRUE
); /* always trace breakpoints */
448 (void) Pfault(P
, FLTWATCH
, TRUE
); /* always trace watchpoints */
449 (void) Pfault(P
, FLTTRACE
, TRUE
); /* always trace single-step */
451 (void) Punsetflags(P
, PR_ASYNC
); /* require synchronous mode */
452 (void) Psetflags(P
, PR_BPTADJ
); /* always adjust eip on x86 */
453 (void) Psetflags(P
, PR_FORK
); /* inherit tracing on fork */
456 * Install event specifiers to track fork and exec activities:
458 (void) mdb_tgt_add_sysexit(t
, SYS_vfork
, hflag
, pt_fork
, NULL
);
459 (void) mdb_tgt_add_sysexit(t
, SYS_forksys
, hflag
, pt_fork
, NULL
);
460 (void) mdb_tgt_add_sysexit(t
, SYS_execve
, hflag
, pt_exec
, NULL
);
463 * Attempt to instantiate the librtld_db agent and set breakpoints
464 * to track rtld activity. We will legitimately fail to instantiate
465 * the rtld_db agent if the target is statically linked.
467 if (pt
->p_rtld
== NULL
&& (pt
->p_rtld
= Prd_agent(P
)) != NULL
) {
471 if ((err
= rd_event_enable(pt
->p_rtld
, TRUE
)) != RD_OK
) {
472 warn("failed to enable rtld_db event tracing: %s\n",
477 if ((err
= rd_event_addr(pt
->p_rtld
, RD_PREINIT
,
478 &rdn
)) == RD_OK
&& rdn
.type
== RD_NOTIFY_BPT
) {
479 (void) mdb_tgt_add_vbrkpt(t
, rdn
.u
.bptaddr
,
480 hflag
, pt_rtld_event
, NULL
);
482 warn("failed to install rtld_db preinit tracing: %s\n",
486 if ((err
= rd_event_addr(pt
->p_rtld
, RD_POSTINIT
,
487 &rdn
)) == RD_OK
&& rdn
.type
== RD_NOTIFY_BPT
) {
488 (void) mdb_tgt_add_vbrkpt(t
, rdn
.u
.bptaddr
,
489 hflag
, pt_rtld_event
, NULL
);
491 warn("failed to install rtld_db postinit tracing: %s\n",
495 if ((err
= rd_event_addr(pt
->p_rtld
, RD_DLACTIVITY
,
496 &rdn
)) == RD_OK
&& rdn
.type
== RD_NOTIFY_BPT
) {
497 (void) mdb_tgt_add_vbrkpt(t
, rdn
.u
.bptaddr
,
498 hflag
, pt_rtld_event
, NULL
);
500 warn("failed to install rtld_db activity tracing: %s\n",
509 * If librtld_db failed to initialize due to an error or because we are
510 * debugging a statically linked executable, allow unscoped references.
512 if (pt
->p_rtld
== NULL
)
513 pt
->p_rtld_finished
= TRUE
;
515 (void) mdb_tgt_sespec_activate_all(t
);
520 pt_vespec_delete(mdb_tgt_t
*t
, void *private, int id
, void *data
)
523 ASSERT(data
== NULL
); /* we don't use any ve_data */
524 (void) mdb_tgt_vespec_delete(t
, id
);
530 pt_pre_detach(mdb_tgt_t
*t
, int clear_matched
)
532 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
533 pt_data_t
*pt
= t
->t_data
;
537 * If we are about to release the process and it is stopped on a traced
538 * SIGINT, breakpoint fault, single-step fault, or watchpoint, make
539 * sure to clear this event prior to releasing the process so that it
540 * does not subsequently reissue the fault and die from SIGTRAP.
542 if (psp
->pr_flags
& PR_ISTOP
) {
543 if (psp
->pr_why
== PR_FAULTED
&& (psp
->pr_what
== FLTBPT
||
544 psp
->pr_what
== FLTTRACE
|| psp
->pr_what
== FLTWATCH
))
546 else if (psp
->pr_why
== PR_SIGNALLED
&& psp
->pr_what
== SIGINT
)
550 (void) write(Pctlfd(t
->t_pshandle
), &cmd
, sizeof (cmd
));
553 if (Pstate(t
->t_pshandle
) == PS_UNDEAD
)
554 (void) waitpid(Pstatus(t
->t_pshandle
)->pr_pid
, NULL
, WNOHANG
);
556 (void) mdb_tgt_vespec_iter(t
, pt_vespec_delete
, NULL
);
557 mdb_tgt_sespec_idle_all(t
, EMDB_NOPROC
, clear_matched
);
559 if (pt
->p_fio
!= pt
->p_aout_fio
) {
561 (void) pt_open_aout(t
, pt
->p_aout_fio
);
565 pt
->p_tdb_ops
= NULL
;
566 pt
->p_ptl_ops
= &proc_lwp_ops
;
567 pt
->p_ptl_hdl
= NULL
;
571 pt
->p_rtld_finished
= FALSE
;
572 pt
->p_rdstate
= PT_RD_NONE
;
576 pt_release_parents(mdb_tgt_t
*t
)
578 struct ps_prochandle
*P
= t
->t_pshandle
;
579 pt_data_t
*pt
= t
->t_data
;
584 while ((vfp
= mdb_list_next(&pt
->p_vforkp
)) != NULL
) {
585 mdb_dprintf(MDB_DBG_TGT
, "releasing vfork parent %d\n",
586 (int)Pstatus(vfp
->p_pshandle
)->pr_pid
);
589 * To release vfork parents, we must also wipe out any armed
590 * events in the parent by switching t_pshandle and calling
591 * se_disarm(). Do not change states or lose the matched list.
593 t
->t_pshandle
= vfp
->p_pshandle
;
595 for (sep
= mdb_list_next(&t
->t_active
); sep
!= NULL
;
596 sep
= mdb_list_next(sep
)) {
597 if (sep
->se_state
== MDB_TGT_SPEC_ARMED
)
598 (void) sep
->se_ops
->se_disarm(t
, sep
);
603 Prelease(vfp
->p_pshandle
, PRELEASE_CLEAR
);
604 mdb_list_delete(&pt
->p_vforkp
, vfp
);
605 mdb_free(vfp
, sizeof (pt_vforkp_t
));
611 pt_fork(mdb_tgt_t
*t
, int vid
, void *private)
613 struct ps_prochandle
*P
= t
->t_pshandle
;
614 const lwpstatus_t
*psp
= &Pstatus(P
)->pr_lwp
;
615 pt_data_t
*pt
= t
->t_data
;
618 int follow_parent
= mdb
.m_forkmode
!= MDB_FM_CHILD
;
619 int is_vfork
= (psp
->pr_what
== SYS_vfork
||
620 (psp
->pr_what
== SYS_forksys
&& psp
->pr_sysarg
[0] == 2));
622 struct ps_prochandle
*C
;
623 const lwpstatus_t
*csp
;
628 mdb_dprintf(MDB_DBG_TGT
, "parent %s: errno=%d rv1=%ld rv2=%ld\n",
629 proc_sysname(psp
->pr_what
, sysname
, sizeof (sysname
)),
630 psp
->pr_errno
, psp
->pr_rval1
, psp
->pr_rval2
);
632 if (psp
->pr_errno
!= 0) {
633 (void) mdb_tgt_continue(t
, NULL
);
634 return; /* fork failed */
638 * If forkmode is ASK and stdout is a terminal, then ask the user to
639 * explicitly set the fork behavior for this particular fork.
641 if (mdb
.m_forkmode
== MDB_FM_ASK
&& mdb
.m_term
!= NULL
) {
642 mdb_iob_printf(mdb
.m_err
, "%s: %s detected: follow (p)arent "
643 "or (c)hild? ", mdb
.m_pname
, sysname
);
644 mdb_iob_flush(mdb
.m_err
);
646 while (IOP_READ(mdb
.m_term
, &c
, sizeof (c
)) == sizeof (c
)) {
647 if (c
== 'P' || c
== 'p') {
648 mdb_iob_printf(mdb
.m_err
, "%c\n", c
);
649 follow_parent
= TRUE
;
651 } else if (c
== 'C' || c
== 'c') {
652 mdb_iob_printf(mdb
.m_err
, "%c\n", c
);
653 follow_parent
= FALSE
;
660 * The parent is now stopped on exit from its fork call. We must now
661 * grab the child on its return from fork in order to manipulate it.
663 if ((C
= Pgrab(psp
->pr_rval1
, PGRAB_RETAIN
, &gcode
)) == NULL
) {
664 warn("failed to grab forked child process %ld: %s\n",
665 psp
->pr_rval1
, Pgrab_error(gcode
));
666 return; /* just stop if we failed to grab the child */
670 * We may have grabbed the child and stopped it prematurely before it
671 * stopped on exit from fork. If so, wait up to 1 sec for it to settle.
673 if (Pstatus(C
)->pr_lwp
.pr_why
!= PR_SYSEXIT
)
674 (void) Pwait(C
, MILLISEC
);
676 csp
= &Pstatus(C
)->pr_lwp
;
678 if (csp
->pr_why
!= PR_SYSEXIT
||
679 (csp
->pr_what
!= SYS_vfork
&& csp
->pr_what
!= SYS_forksys
)) {
680 warn("forked child process %ld did not stop on exit from "
681 "fork as expected\n", psp
->pr_rval1
);
684 warn("target forked child process %ld (debugger following %s)\n",
685 psp
->pr_rval1
, follow_parent
? "parent" : "child");
687 (void) Punsetflags(C
, PR_ASYNC
); /* require synchronous mode */
688 (void) Psetflags(C
, PR_BPTADJ
); /* always adjust eip on x86 */
689 (void) Prd_agent(C
); /* initialize librtld_db */
692 * At the time pt_fork() is called, the target event engine has already
693 * disarmed the specifiers on the active list, clearing out events in
694 * the parent process. However, this means that events that change
695 * the address space (e.g. breakpoints) have not been effectively
696 * disarmed in the child since its address space reflects the state of
697 * the process at the time of fork when events were armed. We must
698 * therefore handle this as a special case and re-invoke the disarm
699 * callback of each active specifier to clean out the child process.
702 for (t
->t_pshandle
= C
, sep
= mdb_list_next(&t
->t_active
);
703 sep
!= NULL
; sep
= mdb_list_next(sep
)) {
704 if (sep
->se_state
== MDB_TGT_SPEC_ACTIVE
)
705 (void) sep
->se_ops
->se_disarm(t
, sep
);
708 t
->t_pshandle
= P
; /* restore pshandle to parent */
712 * If we're following the parent process, we need to temporarily change
713 * t_pshandle to refer to the child handle C so that we can clear out
714 * all the events in the child prior to releasing it below. If we are
715 * tracing a vfork, we also need to explicitly wait for the child to
716 * exec, exit, or die before we can reset and continue the parent. We
717 * avoid having to deal with the vfork child forking again by clearing
718 * PR_FORK and setting PR_RLC; if it does fork it will effectively be
719 * released from our control and we will continue following the parent.
723 mdb_tgt_status_t status
;
725 ASSERT(psp
->pr_flags
& PR_VFORKP
);
726 mdb_tgt_sespec_idle_all(t
, EBUSY
, FALSE
);
729 (void) Psysexit(C
, SYS_execve
, TRUE
);
731 (void) Punsetflags(C
, PR_FORK
| PR_KLC
);
732 (void) Psetflags(C
, PR_RLC
);
735 if (pt_setrun(t
, &status
, 0) == -1 ||
736 status
.st_state
== MDB_TGT_UNDEAD
||
737 status
.st_state
== MDB_TGT_LOST
)
738 break; /* failure or process died */
740 } while (csp
->pr_why
!= PR_SYSEXIT
||
741 csp
->pr_errno
!= 0 || csp
->pr_what
!= SYS_execve
);
747 * If we are following the child, destroy any active libthread_db
748 * handle before we release the parent process.
750 if (!follow_parent
) {
752 pt
->p_tdb_ops
= NULL
;
753 pt
->p_ptl_ops
= &proc_lwp_ops
;
754 pt
->p_ptl_hdl
= NULL
;
758 * Idle all events to make sure the address space and tracing flags are
759 * restored, and then release the process we are not tracing. If we
760 * are following the child of a vfork, we push the parent's pshandle
761 * on to a list of vfork parents to be released when we exec or exit.
763 if (is_vfork
&& !follow_parent
) {
764 pt_vforkp_t
*vfp
= mdb_alloc(sizeof (pt_vforkp_t
), UM_SLEEP
);
766 ASSERT(psp
->pr_flags
& PR_VFORKP
);
768 mdb_list_append(&pt
->p_vforkp
, vfp
);
769 mdb_tgt_sespec_idle_all(t
, EBUSY
, FALSE
);
772 mdb_tgt_sespec_idle_all(t
, EBUSY
, FALSE
);
773 Prelease(t
->t_pshandle
, PRELEASE_CLEAR
);
775 pt_release_parents(t
);
779 * Now that all the hard stuff is done, switch t_pshandle back to the
780 * process we are following and reset our events to the ACTIVE state.
781 * If we are following the child, reset the libthread_db handle as well
788 pt
->p_rtld
= Prd_agent(C
);
789 (void) Pobject_iter(t
->t_pshandle
, (proc_map_f
*)thr_check
, t
);
792 (void) mdb_tgt_sespec_activate_all(t
);
793 (void) mdb_tgt_continue(t
, NULL
);
798 pt_exec(mdb_tgt_t
*t
, int vid
, void *private)
800 struct ps_prochandle
*P
= t
->t_pshandle
;
801 const pstatus_t
*psp
= Pstatus(P
);
802 pt_data_t
*pt
= t
->t_data
;
803 int follow_exec
= mdb
.m_execmode
== MDB_EM_FOLLOW
;
804 pid_t pid
= psp
->pr_pid
;
806 char execname
[MAXPATHLEN
];
807 mdb_sespec_t
*sep
, *nsep
;
811 mdb_dprintf(MDB_DBG_TGT
, "exit from %s: errno=%d\n", proc_sysname(
812 psp
->pr_lwp
.pr_what
, execname
, sizeof (execname
)),
813 psp
->pr_lwp
.pr_errno
);
815 if (psp
->pr_lwp
.pr_errno
!= 0) {
816 (void) mdb_tgt_continue(t
, NULL
);
817 return; /* exec failed */
821 * If execmode is ASK and stdout is a terminal, then ask the user to
822 * explicitly set the exec behavior for this particular exec. If
823 * Pstate() still shows PS_LOST, we are being called from pt_setrun()
824 * directly and therefore we must resume the terminal since it is still
825 * in the suspended state as far as tgt_continue() is concerned.
827 if (mdb
.m_execmode
== MDB_EM_ASK
&& mdb
.m_term
!= NULL
) {
828 if (Pstate(P
) == PS_LOST
)
829 IOP_RESUME(mdb
.m_term
);
831 mdb_iob_printf(mdb
.m_err
, "%s: %s detected: (f)ollow new "
832 "program or (s)top? ", mdb
.m_pname
, execname
);
833 mdb_iob_flush(mdb
.m_err
);
835 while (IOP_READ(mdb
.m_term
, &c
, sizeof (c
)) == sizeof (c
)) {
836 if (c
== 'F' || c
== 'f') {
837 mdb_iob_printf(mdb
.m_err
, "%c\n", c
);
840 } else if (c
== 'S' || c
== 's') {
841 mdb_iob_printf(mdb
.m_err
, "%c\n", c
);
847 if (Pstate(P
) == PS_LOST
)
848 IOP_SUSPEND(mdb
.m_term
);
851 pt_release_parents(t
); /* release any waiting vfork parents */
852 pt_pre_detach(t
, FALSE
); /* remove our breakpoints and idle events */
853 Preset_maps(P
); /* libproc must delete mappings and symtabs */
854 pt_close_aout(t
); /* free pt symbol tables and GElf file data */
857 * If we lost control of the process across the exec and are not able
858 * to reopen it, we have no choice but to clear the matched event list
859 * and wait for the user to quit or otherwise release the process.
861 if (Pstate(P
) == PS_LOST
&& Preopen(P
) == -1) {
864 warn("lost control of PID %d due to exec of %s executable\n",
865 (int)pid
, error
== EOVERFLOW
? "64-bit" : "set-id");
867 for (sep
= t
->t_matched
; sep
!= T_SE_END
; sep
= nsep
) {
868 nsep
= sep
->se_matched
;
869 sep
->se_matched
= NULL
;
870 mdb_tgt_sespec_rele(t
, sep
);
873 if (error
!= EOVERFLOW
)
874 return; /* just stop if we exec'd a set-id executable */
877 if (Pstate(P
) != PS_LOST
) {
878 if (Pexecname(P
, execname
, sizeof (execname
)) == NULL
) {
879 (void) mdb_iob_snprintf(execname
, sizeof (execname
),
880 "/proc/%d/object/a.out", (int)pid
);
883 if (follow_exec
== FALSE
|| psp
->pr_dmodel
== PR_MODEL_NATIVE
)
884 warn("target performed exec of %s\n", execname
);
886 io
= mdb_fdio_create_path(NULL
, execname
, pt
->p_oflags
, 0);
888 warn("failed to open %s", execname
);
889 warn("a.out symbol tables will not be available\n");
890 } else if (pt_open_aout(t
, io
) == NULL
) {
891 (void) mdb_dis_select(pt_disasm(NULL
));
894 (void) mdb_dis_select(pt_disasm(&pt
->p_file
->gf_ehdr
));
898 * We reset our libthread_db state here, but deliberately do NOT call
899 * PTL_DTOR because we do not want to call libthread_db's td_ta_delete.
900 * This interface is hopelessly broken in that it writes to the process
901 * address space (which we do not want it to do after an exec) and it
902 * doesn't bother deallocating any of its storage anyway.
904 pt
->p_tdb_ops
= NULL
;
905 pt
->p_ptl_ops
= &proc_lwp_ops
;
906 pt
->p_ptl_hdl
= NULL
;
908 if (follow_exec
&& psp
->pr_dmodel
!= PR_MODEL_NATIVE
) {
914 if (realpath(getexecname(), execname
) == NULL
) {
915 warn("cannot follow PID %d -- failed to resolve "
916 "debugger pathname for re-exec", (int)pid
);
920 warn("restarting debugger to follow PID %d ...\n", (int)pid
);
921 mdb_dprintf(MDB_DBG_TGT
, "re-exec'ing %s\n", execname
);
923 (void) mdb_snprintf(pidarg
, sizeof (pidarg
), "-p%d", (int)pid
);
925 state
= mdb_get_config();
926 envlen
= strlen(MDB_CONFIG_ENV_VAR
) + 1 + strlen(state
) + 1;
927 env
= mdb_alloc(envlen
, UM_SLEEP
);
928 (void) snprintf(env
, envlen
,
929 "%s=%s", MDB_CONFIG_ENV_VAR
, state
);
933 argv
[0] = mdb
.m_pname
;
937 if (mdb
.m_term
!= NULL
)
938 IOP_SUSPEND(mdb
.m_term
);
940 Prelease(P
, PRELEASE_CLEAR
| PRELEASE_HANG
);
941 (void) execv(execname
, (char *const *)argv
);
942 warn("failed to re-exec debugger");
944 if (mdb
.m_term
!= NULL
)
945 IOP_RESUME(mdb
.m_term
);
947 t
->t_pshandle
= pt
->p_idlehandle
;
951 pt_post_attach(t
); /* install tracing flags and activate events */
952 pt_activate_common(t
); /* initialize librtld_db and libthread_db */
954 if (psp
->pr_dmodel
!= PR_MODEL_NATIVE
&& mdb
.m_term
!= NULL
) {
955 warn("loadable dcmds will not operate on non-native %d-bit "
956 "data model\n", psp
->pr_dmodel
== PR_MODEL_ILP32
? 32 : 64);
957 warn("use ::release -a and then run mdb -p %d to restart "
958 "debugger\n", (int)pid
);
962 (void) mdb_tgt_continue(t
, NULL
);
966 pt_setflags(mdb_tgt_t
*t
, int flags
)
968 pt_data_t
*pt
= t
->t_data
;
970 if ((flags
^ t
->t_flags
) & MDB_TGT_F_RDWR
) {
971 int mode
= (flags
& MDB_TGT_F_RDWR
) ? O_RDWR
: O_RDONLY
;
974 if (pt
->p_fio
== NULL
)
975 return (set_errno(EMDB_NOEXEC
));
977 io
= mdb_fdio_create_path(NULL
, IOP_NAME(pt
->p_fio
), mode
, 0);
980 return (-1); /* errno is set for us */
982 t
->t_flags
= (t
->t_flags
& ~MDB_TGT_F_RDWR
) |
983 (flags
& MDB_TGT_F_RDWR
);
985 pt
->p_fio
= mdb_io_hold(io
);
986 mdb_io_rele(pt
->p_file
->gf_io
);
987 pt
->p_file
->gf_io
= pt
->p_fio
;
990 if (flags
& MDB_TGT_F_FORCE
) {
991 t
->t_flags
|= MDB_TGT_F_FORCE
;
992 pt
->p_gflags
|= PGRAB_FORCE
;
1000 pt_frame(void *arglim
, uintptr_t pc
, uint_t argc
, const long *argv
,
1001 const mdb_tgt_gregset_t
*gregs
)
1003 argc
= MIN(argc
, (uint_t
)(uintptr_t)arglim
);
1004 mdb_printf("%a(", pc
);
1007 mdb_printf("%lr", *argv
++);
1008 for (argc
--; argc
!= 0; argc
--)
1009 mdb_printf(", %lr", *argv
++);
1017 pt_framev(void *arglim
, uintptr_t pc
, uint_t argc
, const long *argv
,
1018 const mdb_tgt_gregset_t
*gregs
)
1020 argc
= MIN(argc
, (uint_t
)(uintptr_t)arglim
);
1021 #if defined(__i386) || defined(__amd64)
1022 mdb_printf("%0?lr %a(", gregs
->gregs
[R_FP
], pc
);
1024 mdb_printf("%0?lr %a(", gregs
->gregs
[R_SP
], pc
);
1027 mdb_printf("%lr", *argv
++);
1028 for (argc
--; argc
!= 0; argc
--)
1029 mdb_printf(", %lr", *argv
++);
1037 pt_framer(void *arglim
, uintptr_t pc
, uint_t argc
, const long *argv
,
1038 const mdb_tgt_gregset_t
*gregs
)
1040 if (pt_frameregs(arglim
, pc
, argc
, argv
, gregs
, pc
== PC_FAKE
) == -1) {
1042 * Use verbose format if register format is not supported.
1044 return (pt_framev(arglim
, pc
, argc
, argv
, gregs
));
1052 pt_stack_common(uintptr_t addr
, uint_t flags
, int argc
,
1053 const mdb_arg_t
*argv
, mdb_tgt_stack_f
*func
, prgreg_t saved_pc
)
1055 void *arg
= (void *)(uintptr_t)mdb
.m_nargs
;
1056 mdb_tgt_t
*t
= mdb
.m_target
;
1057 mdb_tgt_gregset_t gregs
;
1060 if (argv
->a_type
== MDB_TYPE_CHAR
|| argc
> 1)
1061 return (DCMD_USAGE
);
1063 if (argv
->a_type
== MDB_TYPE_STRING
)
1064 arg
= (void *)(uintptr_t)mdb_strtoull(argv
->a_un
.a_str
);
1066 arg
= (void *)(uintptr_t)argv
->a_un
.a_val
;
1069 if (t
->t_pshandle
== NULL
|| Pstate(t
->t_pshandle
) == PS_IDLE
) {
1070 mdb_warn("no process active\n");
1075 * In the universe of sparcv7, sparcv9, ia32, and amd64 this code can be
1076 * common: <sys/procfs_isa.h> conveniently #defines R_FP to be the
1077 * appropriate register we need to set in order to perform a stack
1078 * traceback from a given frame address.
1080 if (flags
& DCMD_ADDRSPEC
) {
1081 bzero(&gregs
, sizeof (gregs
));
1082 gregs
.gregs
[R_FP
] = addr
;
1084 gregs
.gregs
[R_I7
] = saved_pc
;
1085 #endif /* __sparc */
1086 } else if (PTL_GETREGS(t
, PTL_TID(t
), gregs
.gregs
) != 0) {
1087 mdb_warn("failed to get current register set");
1091 (void) mdb_tgt_stack_iter(t
, &gregs
, func
, arg
);
1096 pt_stack(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1098 return (pt_stack_common(addr
, flags
, argc
, argv
, pt_frame
, 0));
1102 pt_stackv(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1104 return (pt_stack_common(addr
, flags
, argc
, argv
, pt_framev
, 0));
1108 pt_stackr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1111 * Force printing of first register window, by setting the
1112 * saved pc (%i7) to PC_FAKE.
1114 return (pt_stack_common(addr
, flags
, argc
, argv
, pt_framer
, PC_FAKE
));
1119 pt_ignored(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1121 struct ps_prochandle
*P
= mdb
.m_target
->t_pshandle
;
1122 char buf
[PRSIGBUFSZ
];
1124 if ((flags
& DCMD_ADDRSPEC
) || argc
!= 0)
1125 return (DCMD_USAGE
);
1128 mdb_warn("no process is currently active\n");
1132 mdb_printf("%s\n", proc_sigset2str(&Pstatus(P
)->pr_sigtrace
, " ",
1133 FALSE
, buf
, sizeof (buf
)));
1140 pt_lwpid(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1142 struct ps_prochandle
*P
= mdb
.m_target
->t_pshandle
;
1144 if ((flags
& DCMD_ADDRSPEC
) || argc
!= 0)
1145 return (DCMD_USAGE
);
1148 mdb_warn("no process is currently active\n");
1152 mdb_printf("%d\n", Pstatus(P
)->pr_lwp
.pr_lwpid
);
1157 pt_print_lwpid(int *n
, const lwpstatus_t
*psp
)
1159 struct ps_prochandle
*P
= mdb
.m_target
->t_pshandle
;
1160 int nlwp
= Pstatus(P
)->pr_nlwp
;
1163 mdb_printf("%d and ", (int)psp
->pr_lwpid
);
1164 else if (*n
== nlwp
- 1)
1165 mdb_printf("%d are", (int)psp
->pr_lwpid
);
1167 mdb_printf("%d, ", (int)psp
->pr_lwpid
);
1175 pt_lwpids(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1177 struct ps_prochandle
*P
= mdb
.m_target
->t_pshandle
;
1181 mdb_warn("no process is currently active\n");
1185 switch (Pstatus(P
)->pr_nlwp
) {
1187 mdb_printf("no lwps are");
1190 mdb_printf("lwpid %d is the only lwp",
1191 Pstatus(P
)->pr_lwp
.pr_lwpid
);
1194 mdb_printf("lwpids ");
1195 (void) Plwp_iter(P
, (proc_lwp_f
*)pt_print_lwpid
, &n
);
1198 switch (Pstate(P
)) {
1200 mdb_printf(" in core of process %d.\n", Pstatus(P
)->pr_pid
);
1203 mdb_printf(" in idle target.\n");
1206 mdb_printf(" in process %d.\n", (int)Pstatus(P
)->pr_pid
);
1215 pt_ignore(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1217 pt_data_t
*pt
= mdb
.m_target
->t_data
;
1219 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
1220 return (DCMD_USAGE
);
1222 if (addr
< 1 || addr
> pt
->p_maxsig
) {
1223 mdb_warn("invalid signal number -- 0t%lu\n", addr
);
1227 (void) mdb_tgt_vespec_iter(mdb
.m_target
, pt_ignore_sig
, (void *)addr
);
1233 pt_attach(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1235 mdb_tgt_t
*t
= mdb
.m_target
;
1236 pt_data_t
*pt
= t
->t_data
;
1239 if (!(flags
& DCMD_ADDRSPEC
) && argc
== 0)
1240 return (DCMD_USAGE
);
1242 if (((flags
& DCMD_ADDRSPEC
) && argc
!= 0) || argc
> 1 ||
1243 (argc
!= 0 && argv
->a_type
!= MDB_TYPE_STRING
))
1244 return (DCMD_USAGE
);
1246 if (t
->t_pshandle
!= NULL
&& Pstate(t
->t_pshandle
) != PS_IDLE
) {
1247 mdb_warn("debugger is already attached to a %s\n",
1248 (Pstate(t
->t_pshandle
) == PS_DEAD
) ? "core" : "process");
1252 if (pt
->p_fio
== NULL
) {
1253 mdb_warn("attach requires executable to be specified on "
1254 "command-line (or use -p)\n");
1258 if (flags
& DCMD_ADDRSPEC
)
1259 t
->t_pshandle
= Pgrab((pid_t
)addr
, pt
->p_gflags
, &perr
);
1261 t
->t_pshandle
= proc_arg_grab(argv
->a_un
.a_str
,
1262 PR_ARG_ANY
, pt
->p_gflags
, &perr
);
1264 if (t
->t_pshandle
== NULL
) {
1265 t
->t_pshandle
= pt
->p_idlehandle
;
1266 mdb_warn("cannot attach: %s\n", Pgrab_error(perr
));
1270 state
= Pstate(t
->t_pshandle
);
1271 if (state
!= PS_DEAD
&& state
!= PS_IDLE
) {
1272 (void) Punsetflags(t
->t_pshandle
, PR_KLC
);
1273 (void) Psetflags(t
->t_pshandle
, PR_RLC
);
1275 pt_activate_common(t
);
1278 (void) mdb_tgt_status(t
, &t
->t_status
);
1279 mdb_module_load_all(0);
1284 pt_regstatus(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1286 mdb_tgt_t
*t
= mdb
.m_target
;
1288 if (t
->t_pshandle
!= NULL
) {
1289 const pstatus_t
*psp
= Pstatus(t
->t_pshandle
);
1290 int cursig
= psp
->pr_lwp
.pr_cursig
;
1291 char signame
[SIG2STR_MAX
];
1292 int state
= Pstate(t
->t_pshandle
);
1294 if (state
!= PS_DEAD
&& state
!= PS_IDLE
)
1295 mdb_printf("process id = %d\n", psp
->pr_pid
);
1297 mdb_printf("no process\n");
1299 if (cursig
!= 0 && sig2str(cursig
, signame
) == 0)
1300 mdb_printf("SIG%s: %s\n", signame
, strsignal(cursig
));
1303 return (pt_regs(addr
, flags
, argc
, argv
));
1307 pt_thread_name(mdb_tgt_t
*t
, mdb_tgt_tid_t tid
, char *buf
, size_t bufsize
)
1309 char name
[THREAD_NAME_MAX
];
1313 if (t
->t_pshandle
== NULL
||
1314 Plwp_getname(t
->t_pshandle
, tid
, name
, sizeof (name
)) != 0 ||
1316 (void) mdb_snprintf(buf
, bufsize
, "%lu", tid
);
1320 (void) mdb_snprintf(buf
, bufsize
, "%lu [%s]", tid
, name
);
1324 pt_findstack(uintptr_t tid
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1326 mdb_tgt_t
*t
= mdb
.m_target
;
1327 mdb_tgt_gregset_t gregs
;
1333 if (!(flags
& DCMD_ADDRSPEC
))
1334 return (DCMD_USAGE
);
1336 count
= mdb_getopts(argc
, argv
, 'v', MDB_OPT_SETBITS
, TRUE
, &showargs
,
1341 if (argc
> 1 || (argc
== 1 && argv
->a_type
!= MDB_TYPE_STRING
))
1342 return (DCMD_USAGE
);
1344 if (PTL_GETREGS(t
, tid
, gregs
.gregs
) != 0) {
1345 mdb_warn("failed to get register set for thread %p", tid
);
1349 pc
= gregs
.gregs
[R_PC
];
1350 #if defined(__i386) || defined(__amd64)
1351 sp
= gregs
.gregs
[R_FP
];
1353 sp
= gregs
.gregs
[R_SP
];
1356 pt_thread_name(t
, tid
, name
, sizeof (name
));
1358 mdb_printf("stack pointer for thread %s: %p\n", name
, sp
);
1360 mdb_printf("[ %0?lr %a() ]\n", sp
, pc
);
1362 (void) mdb_inc_indent(2);
1366 (void) mdb_eval(argv
->a_un
.a_str
);
1368 (void) mdb_eval("<.$C");
1370 (void) mdb_eval("<.$C0");
1372 (void) mdb_dec_indent(2);
1378 pt_gcore(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1380 mdb_tgt_t
*t
= mdb
.m_target
;
1381 char *prefix
= "core";
1382 char *content_str
= NULL
;
1383 core_content_t content
= CC_CONTENT_DEFAULT
;
1388 if (flags
& DCMD_ADDRSPEC
)
1389 return (DCMD_USAGE
);
1391 if (mdb_getopts(argc
, argv
,
1392 'o', MDB_OPT_STR
, &prefix
,
1393 'c', MDB_OPT_STR
, &content_str
, NULL
) != argc
)
1394 return (DCMD_USAGE
);
1396 if (content_str
!= NULL
&&
1397 (proc_str2content(content_str
, &content
) != 0 ||
1398 content
== CC_CONTENT_INVALID
)) {
1399 mdb_warn("invalid content string '%s'\n", content_str
);
1403 if (t
->t_pshandle
== NULL
) {
1404 mdb_warn("no process active\n");
1408 pid
= Pstatus(t
->t_pshandle
)->pr_pid
;
1409 size
= 1 + mdb_snprintf(NULL
, 0, "%s.%d", prefix
, (int)pid
);
1410 fname
= mdb_alloc(size
, UM_SLEEP
| UM_GC
);
1411 (void) mdb_snprintf(fname
, size
, "%s.%d", prefix
, (int)pid
);
1413 if (Pgcore(t
->t_pshandle
, fname
, content
) != 0) {
1415 * Short writes during dumping are specifically described by
1416 * EBADE, just as ZFS uses this otherwise-unused code for
1417 * checksum errors. Translate to and mdb errno.
1420 (void) set_errno(EMDB_SHORTWRITE
);
1421 mdb_warn("couldn't dump core");
1425 mdb_warn("%s dumped\n", fname
);
1432 pt_kill(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1434 mdb_tgt_t
*t
= mdb
.m_target
;
1435 pt_data_t
*pt
= t
->t_data
;
1438 if ((flags
& DCMD_ADDRSPEC
) || argc
!= 0)
1439 return (DCMD_USAGE
);
1441 if (t
->t_pshandle
!= NULL
&&
1442 (state
= Pstate(t
->t_pshandle
)) != PS_DEAD
&& state
!= PS_IDLE
) {
1443 mdb_warn("victim process PID %d forcibly terminated\n",
1444 (int)Pstatus(t
->t_pshandle
)->pr_pid
);
1445 pt_pre_detach(t
, TRUE
);
1446 pt_release_parents(t
);
1447 Prelease(t
->t_pshandle
, PRELEASE_KILL
);
1448 t
->t_pshandle
= pt
->p_idlehandle
;
1449 (void) mdb_tgt_status(t
, &t
->t_status
);
1450 mdb
.m_flags
&= ~(MDB_FL_VCREATE
| MDB_FL_JOBCTL
);
1452 mdb_warn("no victim process is currently under control\n");
1459 pt_detach(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1461 mdb_tgt_t
*t
= mdb
.m_target
;
1462 pt_data_t
*pt
= t
->t_data
;
1463 int rflags
= pt
->p_rflags
;
1465 if (argc
!= 0 && argv
->a_type
== MDB_TYPE_STRING
&&
1466 strcmp(argv
->a_un
.a_str
, "-a") == 0) {
1467 rflags
= PRELEASE_HANG
| PRELEASE_CLEAR
;
1472 if ((flags
& DCMD_ADDRSPEC
) || argc
!= 0)
1473 return (DCMD_USAGE
);
1475 if (t
->t_pshandle
== NULL
|| Pstate(t
->t_pshandle
) == PS_IDLE
) {
1476 mdb_warn("debugger is not currently attached to a process "
1481 pt_pre_detach(t
, TRUE
);
1482 pt_release_parents(t
);
1483 Prelease(t
->t_pshandle
, rflags
);
1484 t
->t_pshandle
= pt
->p_idlehandle
;
1485 (void) mdb_tgt_status(t
, &t
->t_status
);
1486 mdb
.m_flags
&= ~(MDB_FL_VCREATE
| MDB_FL_JOBCTL
);
1492 reg_disc_get(const mdb_var_t
*v
)
1494 mdb_tgt_t
*t
= MDB_NV_COOKIE(v
);
1495 mdb_tgt_tid_t tid
= PTL_TID(t
);
1496 mdb_tgt_reg_t r
= 0;
1498 if (tid
!= (mdb_tgt_tid_t
)-1L)
1499 (void) mdb_tgt_getareg(t
, tid
, mdb_nv_get_name(v
), &r
);
1505 reg_disc_set(mdb_var_t
*v
, uintmax_t r
)
1507 mdb_tgt_t
*t
= MDB_NV_COOKIE(v
);
1508 mdb_tgt_tid_t tid
= PTL_TID(t
);
1510 if (tid
!= (mdb_tgt_tid_t
)-1L && mdb_tgt_putareg(t
, tid
,
1511 mdb_nv_get_name(v
), r
) == -1)
1512 mdb_warn("failed to modify %%%s register", mdb_nv_get_name(v
));
1516 pt_print_reason(const lwpstatus_t
*psp
)
1518 char name
[SIG2STR_MAX
+ 4]; /* enough for SIG+name+\0, syscall or flt */
1521 switch (psp
->pr_why
) {
1523 mdb_printf("stopped by debugger");
1526 mdb_printf("stopped on %s (%s)", proc_signame(psp
->pr_what
,
1527 name
, sizeof (name
)), strsignal(psp
->pr_what
));
1530 mdb_printf("stopped on entry to %s system call",
1531 proc_sysname(psp
->pr_what
, name
, sizeof (name
)));
1534 mdb_printf("stopped on exit from %s system call",
1535 proc_sysname(psp
->pr_what
, name
, sizeof (name
)));
1538 mdb_printf("stopped by job control");
1541 if (psp
->pr_what
== FLTBPT
) {
1542 mdb_printf("stopped on a breakpoint");
1543 } else if (psp
->pr_what
== FLTWATCH
) {
1544 switch (psp
->pr_info
.si_code
) {
1557 mdb_printf("stopped %s a watchpoint (%s access to %p)",
1558 psp
->pr_info
.si_trapafter
? "after" : "on",
1559 desc
, psp
->pr_info
.si_addr
);
1560 } else if (psp
->pr_what
== FLTTRACE
) {
1561 mdb_printf("stopped after a single-step");
1563 mdb_printf("stopped on a %s fault",
1564 proc_fltname(psp
->pr_what
, name
, sizeof (name
)));
1569 mdb_printf("suspended by the kernel");
1572 mdb_printf("stopped for unknown reason (%d/%d)",
1573 psp
->pr_why
, psp
->pr_what
);
1579 pt_status_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1581 mdb_tgt_t
*t
= mdb
.m_target
;
1582 struct ps_prochandle
*P
= t
->t_pshandle
;
1583 pt_data_t
*pt
= t
->t_data
;
1586 const psinfo_t
*pip
= Ppsinfo(P
);
1587 const pstatus_t
*psp
= Pstatus(P
);
1588 int cursig
= 0, bits
= 0, coredump
= 0;
1592 char *panicbuf
= mdb_alloc(PANIC_BUFSIZE
, UM_SLEEP
);
1593 const siginfo_t
*sip
= &(psp
->pr_lwp
.pr_info
);
1595 char execname
[MAXPATHLEN
], buf
[BUFSIZ
];
1596 char signame
[SIG2STR_MAX
+ 4]; /* enough for SIG+name+\0 */
1598 mdb_tgt_spec_desc_t desc
;
1605 (void) strcpy(uts
.nodename
, "unknown machine");
1606 (void) Puname(P
, &uts
);
1609 bcopy(pip
, &pi
, sizeof (psinfo_t
));
1610 proc_unctrl_psinfo(&pi
);
1612 bzero(&pi
, sizeof (psinfo_t
));
1614 bits
= pi
.pr_dmodel
== PR_MODEL_ILP32
? 32 : 64;
1617 if (psp
!= NULL
&& state
!= PS_UNDEAD
&& state
!= PS_IDLE
)
1618 cursig
= psp
->pr_lwp
.pr_cursig
;
1620 if (state
== PS_DEAD
&& pip
!= NULL
) {
1621 mdb_printf("debugging core file of %s (%d-bit) "
1622 "from %s\n", pi
.pr_fname
, bits
, uts
.nodename
);
1624 } else if (state
== PS_DEAD
) {
1625 mdb_printf("debugging core file\n");
1627 } else if (state
== PS_IDLE
) {
1628 const GElf_Ehdr
*ehp
= &pt
->p_file
->gf_ehdr
;
1630 mdb_printf("debugging %s file (%d-bit)\n",
1631 ehp
->e_type
== ET_EXEC
? "executable" : "object",
1632 ehp
->e_ident
[EI_CLASS
] == ELFCLASS32
? 32 : 64);
1634 } else if (state
== PS_UNDEAD
&& pi
.pr_pid
== 0) {
1635 mdb_printf("debugging defunct process\n");
1638 mdb_printf("debugging PID %d (%d-bit)\n",
1642 if (Pexecname(P
, execname
, sizeof (execname
)) != NULL
)
1643 mdb_printf("file: %s\n", execname
);
1645 if (pip
!= NULL
&& state
== PS_DEAD
)
1646 mdb_printf("initial argv: %s\n", pi
.pr_psargs
);
1648 if (state
!= PS_UNDEAD
&& state
!= PS_IDLE
) {
1649 mdb_printf("threading model: ");
1650 if (pt
->p_ptl_ops
== &proc_lwp_ops
)
1651 mdb_printf("raw lwps\n");
1653 mdb_printf("native threads\n");
1656 mdb_printf("status: ");
1659 ASSERT(!(psp
->pr_flags
& PR_STOPPED
));
1660 mdb_printf("process is running");
1661 if (psp
->pr_flags
& PR_DSTOP
)
1662 mdb_printf(", debugger stop directive pending");
1667 ASSERT(psp
->pr_flags
& PR_STOPPED
);
1668 pt_print_reason(&psp
->pr_lwp
);
1670 if (psp
->pr_flags
& PR_DSTOP
)
1671 mdb_printf(", debugger stop directive pending");
1672 if (psp
->pr_flags
& PR_ASLEEP
)
1673 mdb_printf(", sleeping in %s system call",
1674 proc_sysname(psp
->pr_lwp
.pr_syscall
,
1675 signame
, sizeof (signame
)));
1679 for (sep
= t
->t_matched
; sep
!= T_SE_END
;
1680 sep
= sep
->se_matched
) {
1681 mdb_printf("event: %s\n", sep
->se_ops
->se_info(
1682 t
, sep
, mdb_list_next(&sep
->se_velist
),
1683 &desc
, buf
, sizeof (buf
)));
1688 mdb_printf("debugger lost control of process\n");
1692 coredump
= WIFSIGNALED(pi
.pr_wstat
) &&
1693 WCOREDUMP(pi
.pr_wstat
);
1697 if (cursig
== 0 && WIFSIGNALED(pi
.pr_wstat
))
1698 cursig
= WTERMSIG(pi
.pr_wstat
);
1700 * We can only use pr_wstat == 0 as a test for gcore if
1701 * an NT_PRCRED note is present; these features were
1702 * added at the same time in Solaris 8.
1704 if (pi
.pr_wstat
== 0 && Pstate(P
) == PS_DEAD
&&
1705 Pcred(P
, &cred
, 1) == 0) {
1706 mdb_printf("process core file generated "
1708 } else if (cursig
!= 0) {
1709 mdb_printf("process terminated by %s (%s)",
1710 proc_signame(cursig
, signame
,
1711 sizeof (signame
)), strsignal(cursig
));
1713 if (sip
->si_signo
!= 0 && SI_FROMUSER(sip
) &&
1715 mdb_printf(", pid=%d uid=%u",
1716 (int)sip
->si_pid
, sip
->si_uid
);
1717 if (sip
->si_code
!= 0) {
1718 mdb_printf(" code=%d",
1722 switch (sip
->si_signo
) {
1729 mdb_printf(", addr=%p",
1737 mdb_printf(" - core file dumped");
1740 mdb_printf("process terminated with exit "
1741 "status %d\n", WEXITSTATUS(pi
.pr_wstat
));
1744 if (Plookup_by_name(t
->t_pshandle
, "libc.so",
1745 "panicstr", &sym
) == 0 &&
1746 Pread(t
->t_pshandle
, &panicstr
, sizeof (panicstr
),
1747 sym
.st_value
) == sizeof (panicstr
) &&
1748 Pread_string(t
->t_pshandle
, panicbuf
,
1749 PANIC_BUFSIZE
, panicstr
) > 0) {
1750 mdb_printf("panic message: %s",
1758 mdb_printf("idle\n");
1762 mdb_printf("unknown libproc Pstate: %d\n", Pstate(P
));
1764 mdb_free(panicbuf
, PANIC_BUFSIZE
);
1766 } else if (pt
->p_file
!= NULL
) {
1767 const GElf_Ehdr
*ehp
= &pt
->p_file
->gf_ehdr
;
1769 mdb_printf("debugging %s file (%d-bit)\n",
1770 ehp
->e_type
== ET_EXEC
? "executable" : "object",
1771 ehp
->e_ident
[EI_CLASS
] == ELFCLASS32
? 32 : 64);
1772 mdb_printf("executable file: %s\n", IOP_NAME(pt
->p_fio
));
1773 mdb_printf("status: idle\n");
1780 pt_tls(uintptr_t tid
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1786 mdb_tgt_t
*t
= mdb
.m_target
;
1788 if (!(flags
& DCMD_ADDRSPEC
) || argc
> 1)
1789 return (DCMD_USAGE
);
1794 if (tlsbase(t
, tid
, PR_LMID_EVERY
, MDB_TGT_OBJ_EXEC
, &b
) != 0) {
1795 mdb_warn("failed to lookup tlsbase for %r", tid
);
1799 mdb_printf("%lr\n", b
);
1805 name
= argv
[0].a_un
.a_str
;
1806 object
= MDB_TGT_OBJ_EVERY
;
1808 if (pt_lookup_by_name_thr(t
, object
, name
, &sym
, &si
, tid
) != 0) {
1809 mdb_warn("failed to lookup %s", name
);
1810 return (DCMD_ABORT
); /* avoid repeated failure */
1813 if (GELF_ST_TYPE(sym
.st_info
) != STT_TLS
&& DCMD_HDRSPEC(flags
))
1814 mdb_warn("%s does not refer to thread local storage\n", name
);
1816 mdb_printf("%llr\n", sym
.st_value
);
1817 mdb_set_dot(sym
.st_value
);
1824 pt_tmodel(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1826 mdb_tgt_t
*t
= mdb
.m_target
;
1827 pt_data_t
*pt
= t
->t_data
;
1828 const pt_ptl_ops_t
*ptl_ops
;
1830 if (argc
!= 1 || argv
->a_type
!= MDB_TYPE_STRING
)
1831 return (DCMD_USAGE
);
1833 if (strcmp(argv
->a_un
.a_str
, "thread") == 0)
1834 ptl_ops
= &proc_tdb_ops
;
1835 else if (strcmp(argv
->a_un
.a_str
, "lwp") == 0)
1836 ptl_ops
= &proc_lwp_ops
;
1838 return (DCMD_USAGE
);
1840 if (t
->t_pshandle
!= NULL
&& pt
->p_ptl_ops
!= ptl_ops
) {
1842 pt
->p_tdb_ops
= NULL
;
1843 pt
->p_ptl_ops
= &proc_lwp_ops
;
1844 pt
->p_ptl_hdl
= NULL
;
1846 if (ptl_ops
== &proc_tdb_ops
) {
1847 (void) Pobject_iter(t
->t_pshandle
, (proc_map_f
*)
1852 (void) mdb_tgt_status(t
, &t
->t_status
);
1857 env_match(const char *cmp
, const char *nameval
)
1860 size_t cmplen
= strlen(cmp
);
1862 loc
= strchr(nameval
, '=');
1863 if (loc
!= NULL
&& (loc
- nameval
) == cmplen
&&
1864 strncmp(nameval
, cmp
, cmplen
) == 0) {
1873 print_env(void *data
, struct ps_prochandle
*P
, uintptr_t addr
,
1874 const char *nameval
)
1878 if (nameval
== NULL
) {
1879 mdb_printf("<0x%p>\n", addr
);
1882 mdb_printf("%s\n", nameval
);
1883 else if ((value
= env_match(data
, nameval
)) != NULL
)
1884 mdb_printf("%s\n", value
);
1892 pt_getenv(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1894 mdb_tgt_t
*t
= mdb
.m_target
;
1895 pt_data_t
*pt
= t
->t_data
;
1900 i
= mdb_getopts(argc
, argv
,
1901 't', MDB_OPT_SETBITS
, TRUE
, &opt_t
, NULL
);
1906 if ((flags
& DCMD_ADDRSPEC
) || argc
> 1)
1907 return (DCMD_USAGE
);
1909 if (argc
== 1 && argv
->a_type
!= MDB_TYPE_STRING
)
1910 return (DCMD_USAGE
);
1912 if (opt_t
&& t
->t_pshandle
== NULL
) {
1913 mdb_warn("no process active\n");
1917 if (opt_t
&& (Pstate(t
->t_pshandle
) == PS_IDLE
||
1918 Pstate(t
->t_pshandle
) == PS_UNDEAD
)) {
1919 mdb_warn("-t option requires target to be running\n");
1924 if (Penv_iter(t
->t_pshandle
, print_env
,
1925 argc
== 0 ? NULL
: (void *)argv
->a_un
.a_str
) != 0)
1927 } else if (argc
== 1) {
1928 if ((v
= mdb_nv_lookup(&pt
->p_env
, argv
->a_un
.a_str
)) == NULL
)
1931 ASSERT(strchr(mdb_nv_get_cookie(v
), '=') != NULL
);
1932 mdb_printf("%s\n", strchr(mdb_nv_get_cookie(v
), '=') + 1);
1935 mdb_nv_rewind(&pt
->p_env
);
1936 while ((v
= mdb_nv_advance(&pt
->p_env
)) != NULL
)
1937 mdb_printf("%s\n", mdb_nv_get_cookie(v
));
1944 * Function to set a variable in the internal environment, which is used when
1945 * creating new processes. Note that it is possible that 'nameval' can refer to
1946 * read-only memory, if mdb calls putenv() on an existing value before calling
1947 * this function. While we should avoid this situation, this function is
1948 * designed to be robust in the face of such changes.
1951 pt_env_set(pt_data_t
*pt
, const char *nameval
)
1958 if ((equals
= strchr(nameval
, '=')) != NULL
) {
1959 val
= strdup(nameval
);
1960 equals
= val
+ (equals
- nameval
);
1963 * nameval doesn't contain an equals character. Convert this to
1966 len
= strlen(nameval
);
1967 val
= mdb_alloc(len
+ 2, UM_SLEEP
);
1968 (void) mdb_snprintf(val
, len
+ 2, "%s=", nameval
);
1972 /* temporary truncate the string for lookup/insert */
1974 v
= mdb_nv_lookup(&pt
->p_env
, val
);
1977 char *old
= mdb_nv_get_cookie(v
);
1978 mdb_free(old
, strlen(old
) + 1);
1979 name
= mdb_nv_get_name(v
);
1982 * The environment is created using MDB_NV_EXTNAME, so we must
1983 * provide external storage for the variable names.
1990 (void) mdb_nv_insert(&pt
->p_env
, name
, NULL
, (uintptr_t)val
,
1998 * Clears the internal environment.
2001 pt_env_clear(pt_data_t
*pt
)
2006 mdb_nv_rewind(&pt
->p_env
);
2007 while ((v
= mdb_nv_advance(&pt
->p_env
)) != NULL
) {
2009 name
= (char *)mdb_nv_get_name(v
);
2010 val
= mdb_nv_get_cookie(v
);
2012 mdb_nv_remove(&pt
->p_env
, v
);
2014 mdb_free(name
, strlen(name
) + 1);
2015 mdb_free(val
, strlen(val
) + 1);
2021 pt_setenv(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2023 mdb_tgt_t
*t
= mdb
.m_target
;
2024 pt_data_t
*pt
= t
->t_data
;
2029 if ((flags
& DCMD_ADDRSPEC
) || argc
== 0 || argc
> 2)
2030 return (DCMD_USAGE
);
2032 if ((argc
> 0 && argv
[0].a_type
!= MDB_TYPE_STRING
) ||
2033 (argc
> 1 && argv
[1].a_type
!= MDB_TYPE_STRING
))
2034 return (DCMD_USAGE
);
2036 if (t
->t_pshandle
== NULL
) {
2037 mdb_warn("no process active\n");
2042 * If the process is in some sort of running state, warn the user that
2043 * changes won't immediately take effect.
2045 if (Pstate(t
->t_pshandle
) == PS_RUN
||
2046 Pstate(t
->t_pshandle
) == PS_STOP
) {
2047 mdb_warn("warning: changes will not take effect until process"
2052 * We allow two forms of operation. The first is the usual "name=value"
2053 * parameter. We also allow the user to specify two arguments, where
2054 * the first is the name of the variable, and the second is the value.
2058 nameval
= (char *)argv
->a_un
.a_str
;
2060 len
= strlen(argv
[0].a_un
.a_str
) +
2061 strlen(argv
[1].a_un
.a_str
) + 2;
2062 nameval
= mdb_alloc(len
, UM_SLEEP
);
2063 (void) mdb_snprintf(nameval
, len
, "%s=%s", argv
[0].a_un
.a_str
,
2064 argv
[1].a_un
.a_str
);
2068 pt_env_set(pt
, nameval
);
2071 mdb_free(nameval
, strlen(nameval
) + 1);
2078 pt_unsetenv(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2080 mdb_tgt_t
*t
= mdb
.m_target
;
2081 pt_data_t
*pt
= t
->t_data
;
2085 if ((flags
& DCMD_ADDRSPEC
) || argc
> 1)
2086 return (DCMD_USAGE
);
2088 if (argc
== 1 && argv
->a_type
!= MDB_TYPE_STRING
)
2089 return (DCMD_USAGE
);
2091 if (t
->t_pshandle
== NULL
) {
2092 mdb_warn("no process active\n");
2097 * If the process is in some sort of running state, warn the user that
2098 * changes won't immediately take effect.
2100 if (Pstate(t
->t_pshandle
) == PS_RUN
||
2101 Pstate(t
->t_pshandle
) == PS_STOP
) {
2102 mdb_warn("warning: changes will not take effect until process"
2109 if ((v
= mdb_nv_lookup(&pt
->p_env
, argv
->a_un
.a_str
)) != NULL
) {
2110 name
= (char *)mdb_nv_get_name(v
);
2111 value
= mdb_nv_get_cookie(v
);
2113 mdb_nv_remove(&pt
->p_env
, v
);
2115 mdb_free(name
, strlen(name
) + 1);
2116 mdb_free(value
, strlen(value
) + 1);
2126 mdb_printf("-t show current process environment"
2127 " instead of initial environment.\n");
2130 static const mdb_dcmd_t pt_dcmds
[] = {
2131 { "$c", "?[cnt]", "print stack backtrace", pt_stack
},
2132 { "$C", "?[cnt]", "print stack backtrace", pt_stackv
},
2133 { "$i", NULL
, "print signals that are ignored", pt_ignored
},
2134 { "$l", NULL
, "print the representative thread's lwp id", pt_lwpid
},
2135 { "$L", NULL
, "print list of the active lwp ids", pt_lwpids
},
2136 { "$r", "?[-u]", "print general-purpose registers", pt_regs
},
2137 { "$x", "?", "print floating point registers", pt_fpregs
},
2138 { "$X", "?", "print floating point registers", pt_fpregs
},
2139 { "$y", "?", "print floating point registers", pt_fpregs
},
2140 { "$Y", "?", "print floating point registers", pt_fpregs
},
2141 { "$?", "?", "print status and registers", pt_regstatus
},
2142 { ":A", "?[core|pid]", "attach to process or core file", pt_attach
},
2143 { ":i", ":", "ignore signal (delete all matching events)", pt_ignore
},
2144 { ":k", NULL
, "forcibly kill and release target", pt_kill
},
2145 { ":R", "[-a]", "release the previously attached process", pt_detach
},
2146 { "attach", "?[core|pid]",
2147 "attach to process or core file", pt_attach
},
2148 { "findstack", ":[-v]", "find user thread stack", pt_findstack
},
2149 { "gcore", "[-o prefix] [-c content]",
2150 "produce a core file for the attached process", pt_gcore
},
2151 { "getenv", "[-t] [name]", "display an environment variable",
2152 pt_getenv
, getenv_help
},
2153 { "kill", NULL
, "forcibly kill and release target", pt_kill
},
2154 { "release", "[-a]",
2155 "release the previously attached process", pt_detach
},
2156 { "regs", "?[-u]", "print general-purpose registers", pt_regs
},
2157 { "fpregs", "?[-dqs]", "print floating point registers", pt_fpregs
},
2158 { "setenv", "name=value", "set an environment variable", pt_setenv
},
2159 { "stack", "?[cnt]", "print stack backtrace", pt_stack
},
2160 { "stackregs", "?", "print stack backtrace and registers", pt_stackr
},
2161 { "status", NULL
, "print summary of current target", pt_status_dcmd
},
2163 "lookup TLS data in the context of a given thread", pt_tls
},
2164 { "tmodel", "{thread|lwp}", NULL
, pt_tmodel
},
2165 { "unsetenv", "[name]", "clear an environment variable", pt_unsetenv
},
2170 pt_thr_walk_fini(mdb_walk_state_t
*wsp
)
2172 mdb_addrvec_destroy(wsp
->walk_data
);
2173 mdb_free(wsp
->walk_data
, sizeof (mdb_addrvec_t
));
2177 pt_thr_walk_init(mdb_walk_state_t
*wsp
)
2179 wsp
->walk_data
= mdb_zalloc(sizeof (mdb_addrvec_t
), UM_SLEEP
);
2180 mdb_addrvec_create(wsp
->walk_data
);
2182 if (PTL_ITER(mdb
.m_target
, wsp
->walk_data
) == -1) {
2183 mdb_warn("failed to iterate over threads");
2184 pt_thr_walk_fini(wsp
);
2192 pt_thr_walk_step(mdb_walk_state_t
*wsp
)
2194 if (mdb_addrvec_length(wsp
->walk_data
) != 0) {
2195 return (wsp
->walk_callback(mdb_addrvec_shift(wsp
->walk_data
),
2196 NULL
, wsp
->walk_cbdata
));
2201 static const mdb_walker_t pt_walkers
[] = {
2202 { "thread", "walk list of valid thread identifiers",
2203 pt_thr_walk_init
, pt_thr_walk_step
, pt_thr_walk_fini
},
2208 pt_agent_check(boolean_t
*agent
, const lwpstatus_t
*psp
)
2210 if (psp
->pr_flags
& PR_AGENT
)
2217 pt_activate_common(mdb_tgt_t
*t
)
2219 pt_data_t
*pt
= t
->t_data
;
2220 boolean_t hasagent
= B_FALSE
;
2224 * If we have a libproc handle and AT_BASE is set, the process or core
2225 * is dynamically linked. We call Prd_agent() to force libproc to
2226 * try to initialize librtld_db, and issue a warning if that fails.
2228 if (t
->t_pshandle
!= NULL
&& Pgetauxval(t
->t_pshandle
,
2229 AT_BASE
) != -1L && Prd_agent(t
->t_pshandle
) == NULL
) {
2230 mdb_warn("warning: librtld_db failed to initialize; shared "
2231 "library information will not be available\n");
2234 if (t
->t_pshandle
!= NULL
) {
2235 (void) Plwp_iter(t
->t_pshandle
,
2236 (proc_lwp_f
*)pt_agent_check
, &hasagent
);
2240 mdb_warn("agent lwp detected; forcing "
2241 "lwp thread model (use ::tmodel to change)\n");
2242 } else if (t
->t_pshandle
!= NULL
&& Pstate(t
->t_pshandle
) != PS_IDLE
) {
2244 * If we have a libproc handle and we do not have an agent LWP,
2245 * look for the correct thread debugging library. (If we have
2246 * an agent LWP, we leave the model as the raw LWP model to
2247 * allow the agent LWP to be visible to the debugger.)
2249 (void) Pobject_iter(t
->t_pshandle
, (proc_map_f
*)thr_check
, t
);
2253 * If there's a global object named '_mdb_abort_info', assuming we're
2254 * debugging mdb itself and load the developer support module.
2256 if (mdb_gelf_symtab_lookup_by_name(pt
->p_symtab
, "_mdb_abort_info",
2257 &sym
, NULL
) == 0 && GELF_ST_TYPE(sym
.st_info
) == STT_OBJECT
) {
2258 if (mdb_module_load("mdb_ds", MDB_MOD_SILENT
) < 0)
2259 mdb_warn("warning: failed to load developer support\n");
2262 mdb_tgt_elf_export(pt
->p_file
);
2266 pt_activate(mdb_tgt_t
*t
)
2268 static const mdb_nv_disc_t reg_disc
= { reg_disc_set
, reg_disc_get
};
2270 pt_data_t
*pt
= t
->t_data
;
2271 struct utsname u1
, u2
;
2273 core_content_t content
;
2275 if (t
->t_pshandle
) {
2276 mdb_prop_postmortem
= (Pstate(t
->t_pshandle
) == PS_DEAD
);
2277 mdb_prop_kernel
= FALSE
;
2279 mdb_prop_kernel
= mdb_prop_postmortem
= FALSE
;
2281 mdb_prop_datamodel
= MDB_TGT_MODEL_NATIVE
;
2284 * If we're examining a core file that doesn't contain program text,
2285 * and uname(2) doesn't match the NT_UTSNAME note recorded in the
2286 * core file, issue a warning.
2288 if (mdb_prop_postmortem
== TRUE
&&
2289 ((content
= Pcontent(t
->t_pshandle
)) == CC_CONTENT_INVALID
||
2290 !(content
& CC_CONTENT_TEXT
)) &&
2291 uname(&u1
) >= 0 && Puname(t
->t_pshandle
, &u2
) == 0 &&
2292 (strcmp(u1
.release
, u2
.release
) != 0 ||
2293 strcmp(u1
.version
, u2
.version
) != 0)) {
2294 mdb_warn("warning: core file is from %s %s %s; shared text "
2295 "mappings may not match installed libraries\n",
2296 u2
.sysname
, u2
.release
, u2
.version
);
2300 * Perform the common initialization tasks -- these are shared with
2301 * the pt_exec() and pt_run() subroutines.
2303 pt_activate_common(t
);
2305 (void) mdb_tgt_register_dcmds(t
, &pt_dcmds
[0], MDB_MOD_FORCE
);
2306 (void) mdb_tgt_register_walkers(t
, &pt_walkers
[0], MDB_MOD_FORCE
);
2309 * Iterate through our register description list and export
2310 * each register as a named variable.
2312 mdb_nv_rewind(&pt
->p_regs
);
2313 while ((v
= mdb_nv_advance(&pt
->p_regs
)) != NULL
) {
2314 ushort_t rd_flags
= MDB_TGT_R_FLAGS(mdb_nv_get_value(v
));
2316 if (!(rd_flags
& MDB_TGT_R_EXPORT
))
2317 continue; /* Don't export register as a variable */
2319 (void) mdb_nv_insert(&mdb
.m_nv
, mdb_nv_get_name(v
), ®_disc
,
2320 (uintptr_t)t
, MDB_NV_PERSIST
);
2325 pt_deactivate(mdb_tgt_t
*t
)
2327 pt_data_t
*pt
= t
->t_data
;
2328 const mdb_dcmd_t
*dcp
;
2329 const mdb_walker_t
*wp
;
2332 mdb_nv_rewind(&pt
->p_regs
);
2333 while ((v
= mdb_nv_advance(&pt
->p_regs
)) != NULL
) {
2334 ushort_t rd_flags
= MDB_TGT_R_FLAGS(mdb_nv_get_value(v
));
2336 if (!(rd_flags
& MDB_TGT_R_EXPORT
))
2337 continue; /* Didn't export register as a variable */
2339 if (w
= mdb_nv_lookup(&mdb
.m_nv
, mdb_nv_get_name(v
))) {
2340 w
->v_flags
&= ~MDB_NV_PERSIST
;
2341 mdb_nv_remove(&mdb
.m_nv
, w
);
2345 for (wp
= &pt_walkers
[0]; wp
->walk_name
!= NULL
; wp
++) {
2346 if (mdb_module_remove_walker(t
->t_module
, wp
->walk_name
) == -1)
2347 warn("failed to remove walk %s", wp
->walk_name
);
2350 for (dcp
= &pt_dcmds
[0]; dcp
->dc_name
!= NULL
; dcp
++) {
2351 if (mdb_module_remove_dcmd(t
->t_module
, dcp
->dc_name
) == -1)
2352 warn("failed to remove dcmd %s", dcp
->dc_name
);
2355 mdb_prop_postmortem
= FALSE
;
2356 mdb_prop_kernel
= FALSE
;
2357 mdb_prop_datamodel
= MDB_TGT_MODEL_UNKNOWN
;
2361 pt_periodic(mdb_tgt_t
*t
)
2363 pt_data_t
*pt
= t
->t_data
;
2365 if (pt
->p_rdstate
== PT_RD_CONSIST
) {
2366 if (t
->t_pshandle
!= NULL
&& Pstate(t
->t_pshandle
) < PS_LOST
&&
2367 !(mdb
.m_flags
& MDB_FL_NOMODS
)) {
2368 mdb_printf("%s: You've got symbols!\n", mdb
.m_pname
);
2369 mdb_module_load_all(0);
2371 pt
->p_rdstate
= PT_RD_NONE
;
2376 pt_destroy(mdb_tgt_t
*t
)
2378 pt_data_t
*pt
= t
->t_data
;
2380 if (pt
->p_idlehandle
!= NULL
&& pt
->p_idlehandle
!= t
->t_pshandle
)
2381 Prelease(pt
->p_idlehandle
, 0);
2383 if (t
->t_pshandle
!= NULL
) {
2385 pt_release_parents(t
);
2386 pt_pre_detach(t
, TRUE
);
2387 Prelease(t
->t_pshandle
, pt
->p_rflags
);
2390 mdb
.m_flags
&= ~(MDB_FL_VCREATE
| MDB_FL_JOBCTL
);
2393 if (pt
->p_aout_fio
!= NULL
)
2394 mdb_io_rele(pt
->p_aout_fio
);
2397 mdb_nv_destroy(&pt
->p_env
);
2399 mdb_nv_destroy(&pt
->p_regs
);
2400 mdb_free(pt
, sizeof (pt_data_t
));
2405 pt_name(mdb_tgt_t
*t
)
2411 pt_platform(mdb_tgt_t
*t
)
2413 pt_data_t
*pt
= t
->t_data
;
2415 if (t
->t_pshandle
!= NULL
&&
2416 Pplatform(t
->t_pshandle
, pt
->p_platform
, MAXNAMELEN
) != NULL
)
2417 return (pt
->p_platform
);
2419 return (mdb_conf_platform());
2423 pt_uname(mdb_tgt_t
*t
, struct utsname
*utsp
)
2425 if (t
->t_pshandle
!= NULL
)
2426 return (Puname(t
->t_pshandle
, utsp
));
2428 return (uname(utsp
) >= 0 ? 0 : -1);
2432 pt_dmodel(mdb_tgt_t
*t
)
2434 if (t
->t_pshandle
== NULL
)
2435 return (MDB_TGT_MODEL_NATIVE
);
2437 switch (Pstatus(t
->t_pshandle
)->pr_dmodel
) {
2438 case PR_MODEL_ILP32
:
2439 return (MDB_TGT_MODEL_ILP32
);
2441 return (MDB_TGT_MODEL_LP64
);
2444 return (MDB_TGT_MODEL_UNKNOWN
);
2448 pt_vread(mdb_tgt_t
*t
, void *buf
, size_t nbytes
, uintptr_t addr
)
2453 * If no handle is open yet, reads from virtual addresses are
2454 * allowed to succeed but return zero-filled memory.
2456 if (t
->t_pshandle
== NULL
) {
2461 if ((n
= Pread(t
->t_pshandle
, buf
, nbytes
, addr
)) <= 0)
2462 return (set_errno(EMDB_NOMAP
));
2468 pt_vwrite(mdb_tgt_t
*t
, const void *buf
, size_t nbytes
, uintptr_t addr
)
2473 * If no handle is open yet, writes to virtual addresses are
2474 * allowed to succeed but do not actually modify anything.
2476 if (t
->t_pshandle
== NULL
)
2479 n
= Pwrite(t
->t_pshandle
, buf
, nbytes
, addr
);
2481 if (n
== -1 && errno
== EIO
)
2482 return (set_errno(EMDB_NOMAP
));
2488 pt_fread(mdb_tgt_t
*t
, void *buf
, size_t nbytes
, uintptr_t addr
)
2490 pt_data_t
*pt
= t
->t_data
;
2492 if (pt
->p_file
!= NULL
) {
2493 return (mdb_gelf_rw(pt
->p_file
, buf
, nbytes
, addr
,
2494 IOPF_READ(pt
->p_fio
), GIO_READ
));
2502 pt_fwrite(mdb_tgt_t
*t
, const void *buf
, size_t nbytes
, uintptr_t addr
)
2504 pt_data_t
*pt
= t
->t_data
;
2506 if (pt
->p_file
!= NULL
) {
2507 return (mdb_gelf_rw(pt
->p_file
, (void *)buf
, nbytes
, addr
,
2508 IOPF_WRITE(pt
->p_fio
), GIO_WRITE
));
2515 pt_resolve_lmid(const char *object
, Lmid_t
*lmidp
)
2517 Lmid_t lmid
= PR_LMID_EVERY
;
2520 if (object
== MDB_TGT_OBJ_EVERY
|| object
== MDB_TGT_OBJ_EXEC
)
2521 lmid
= LM_ID_BASE
; /* restrict scope to a.out's link map */
2522 else if (object
!= MDB_TGT_OBJ_RTLD
&& strncmp(object
, "LM", 2) == 0 &&
2523 (p
= strchr(object
, '`')) != NULL
) {
2524 object
+= 2; /* skip past initial "LM" prefix */
2525 lmid
= strntoul(object
, (size_t)(p
- object
), mdb
.m_radix
);
2526 object
= p
+ 1; /* skip past link map specifier */
2534 tlsbase(mdb_tgt_t
*t
, mdb_tgt_tid_t tid
, Lmid_t lmid
, const char *object
,
2537 pt_data_t
*pt
= t
->t_data
;
2538 const rd_loadobj_t
*loadobjp
;
2542 if (object
== MDB_TGT_OBJ_EVERY
)
2543 return (set_errno(EINVAL
));
2545 if (t
->t_pshandle
== NULL
|| Pstate(t
->t_pshandle
) == PS_IDLE
)
2546 return (set_errno(EMDB_NOPROC
));
2548 if (pt
->p_tdb_ops
== NULL
)
2549 return (set_errno(EMDB_TDB
));
2551 err
= pt
->p_tdb_ops
->td_ta_map_id2thr(pt
->p_ptl_hdl
, tid
, &th
);
2553 return (set_errno(tdb_to_errno(err
)));
2556 * If this fails, rtld_db has failed to initialize properly.
2558 if ((loadobjp
= Plmid_to_loadobj(t
->t_pshandle
, lmid
, object
)) == NULL
)
2559 return (set_errno(EMDB_NORTLD
));
2562 * This will fail if the TLS block has not been allocated for the
2563 * object that contains the TLS symbol in question.
2565 err
= pt
->p_tdb_ops
->td_thr_tlsbase(&th
, loadobjp
->rl_tlsmodid
, basep
);
2567 return (set_errno(tdb_to_errno(err
)));
2574 const char *pl_name
;
2577 mdb_syminfo_t
*pl_sip
;
2578 mdb_tgt_tid_t pl_tid
;
2579 mdb_bool_t pl_found
;
2584 pt_lookup_cb(void *data
, const prmap_t
*pmp
, const char *object
)
2586 pt_lookup_t
*plp
= data
;
2587 struct ps_prochandle
*P
= plp
->pl_tgt
->t_pshandle
;
2591 if (Pxlookup_by_name(P
, plp
->pl_lmid
, object
, plp
->pl_name
, &sym
,
2596 * If we encounter a match with SHN_UNDEF, keep looking for a
2597 * better match. Return the first match with SHN_UNDEF set if no
2598 * better match is found.
2600 if (sym
.st_shndx
== SHN_UNDEF
) {
2601 if (!plp
->pl_found
) {
2602 plp
->pl_found
= TRUE
;
2603 *plp
->pl_symp
= sym
;
2604 plp
->pl_sip
->sym_table
= si
.prs_table
;
2605 plp
->pl_sip
->sym_id
= si
.prs_id
;
2612 * Note that if the symbol's st_shndx is SHN_UNDEF we don't have the
2613 * TLS offset anyway, so adding in the tlsbase would be worthless.
2615 if (GELF_ST_TYPE(sym
.st_info
) == STT_TLS
&&
2616 plp
->pl_tid
!= (mdb_tgt_tid_t
)-1) {
2619 if (tlsbase(plp
->pl_tgt
, plp
->pl_tid
, plp
->pl_lmid
, object
,
2621 return (-1); /* errno is set for us */
2623 sym
.st_value
+= base
;
2626 plp
->pl_found
= TRUE
;
2627 *plp
->pl_symp
= sym
;
2628 plp
->pl_sip
->sym_table
= si
.prs_table
;
2629 plp
->pl_sip
->sym_id
= si
.prs_id
;
2635 * Lookup the symbol with a thread context so that we can adjust TLS symbols
2636 * to get the values as they would appear in the context of the given thread.
2639 pt_lookup_by_name_thr(mdb_tgt_t
*t
, const char *object
,
2640 const char *name
, GElf_Sym
*symp
, mdb_syminfo_t
*sip
, mdb_tgt_tid_t tid
)
2642 struct ps_prochandle
*P
= t
->t_pshandle
;
2643 pt_data_t
*pt
= t
->t_data
;
2646 const rd_loadobj_t
*aout_lop
;
2648 object
= pt_resolve_lmid(object
, &lmid
);
2659 pl
.pl_found
= FALSE
;
2661 if (object
== MDB_TGT_OBJ_EVERY
) {
2662 if (Pobject_iter_resolved(P
, pt_lookup_cb
, &pl
) == -1)
2663 return (-1); /* errno is set for us */
2664 if ((!pl
.pl_found
) &&
2665 (Pobject_iter(P
, pt_lookup_cb
, &pl
) == -1))
2666 return (-1); /* errno is set for us */
2671 * This can fail either due to an invalid lmid or
2672 * an invalid object. To determine which is
2673 * faulty, we test the lmid against known valid
2674 * lmids and then see if using a wild-card lmid
2675 * improves ths situation.
2677 if ((pmp
= Plmid_to_map(P
, lmid
, object
)) == NULL
) {
2678 if (lmid
!= PR_LMID_EVERY
&&
2679 lmid
!= LM_ID_BASE
&&
2680 lmid
!= LM_ID_LDSO
&&
2681 Plmid_to_map(P
, PR_LMID_EVERY
, object
)
2683 return (set_errno(EMDB_NOLMID
));
2685 return (set_errno(EMDB_NOOBJ
));
2688 if (pt_lookup_cb(&pl
, pmp
, object
) == -1)
2689 return (-1); /* errno is set for us */
2697 * If libproc doesn't have the symbols for rtld, we're cooked --
2698 * mdb doesn't have those symbols either.
2700 if (object
== MDB_TGT_OBJ_RTLD
)
2701 return (set_errno(EMDB_NOSYM
));
2703 if (object
!= MDB_TGT_OBJ_EXEC
&& object
!= MDB_TGT_OBJ_EVERY
) {
2704 int status
= mdb_gelf_symtab_lookup_by_file(pt
->p_symtab
,
2705 object
, name
, symp
, &sip
->sym_id
);
2709 Plmid_to_map(P
, PR_LMID_EVERY
, object
) != NULL
)
2710 return (set_errno(EMDB_NOSYM
));
2712 return (-1); /* errno set from lookup_by_file */
2718 if (mdb_gelf_symtab_lookup_by_name(pt
->p_symtab
, name
, symp
, &i
) == 0) {
2719 sip
->sym_table
= MDB_TGT_SYMTAB
;
2724 if (mdb_gelf_symtab_lookup_by_name(pt
->p_dynsym
, name
, symp
, &i
) == 0) {
2725 sip
->sym_table
= MDB_TGT_DYNSYM
;
2730 return (set_errno(EMDB_NOSYM
));
2733 if (pt
->p_file
!= NULL
&&
2734 pt
->p_file
->gf_ehdr
.e_type
== ET_DYN
&&
2736 (aout_lop
= Pname_to_loadobj(P
, PR_OBJ_EXEC
)) != NULL
)
2737 symp
->st_value
+= aout_lop
->rl_base
;
2741 * If the symbol has type TLS, libproc should have found the symbol
2742 * if it exists and has been allocated.
2744 if (GELF_ST_TYPE(symp
->st_info
) == STT_TLS
)
2745 return (set_errno(EMDB_TLS
));
2751 pt_lookup_by_name(mdb_tgt_t
*t
, const char *object
,
2752 const char *name
, GElf_Sym
*symp
, mdb_syminfo_t
*sip
)
2754 return (pt_lookup_by_name_thr(t
, object
, name
, symp
, sip
, PTL_TID(t
)));
2758 pt_lookup_by_addr(mdb_tgt_t
*t
, uintptr_t addr
, uint_t flags
,
2759 char *buf
, size_t nbytes
, GElf_Sym
*symp
, mdb_syminfo_t
*sip
)
2761 struct ps_prochandle
*P
= t
->t_pshandle
;
2762 pt_data_t
*pt
= t
->t_data
;
2763 rd_plt_info_t rpi
= { 0 };
2768 mdb_gelf_symtab_t
*gsts
[3]; /* mdb.m_prsym, .symtab, .dynsym */
2769 int gstc
= 0; /* number of valid gsts[] entries */
2771 mdb_gelf_symtab_t
*gst
= NULL
; /* set if 'sym' is from a gst */
2772 const prmap_t
*pmp
= NULL
; /* set if 'sym' is from libproc */
2773 GElf_Sym sym
; /* best symbol found so far if !exact */
2777 * Fill in our array of symbol table pointers with the private symbol
2778 * table, static symbol table, and dynamic symbol table if applicable.
2779 * These are done in order of precedence so that if we match and
2780 * MDB_TGT_SYM_EXACT is set, we need not look any further.
2782 if (mdb
.m_prsym
!= NULL
)
2783 gsts
[gstc
++] = mdb
.m_prsym
;
2784 if (P
== NULL
&& pt
->p_symtab
!= NULL
)
2785 gsts
[gstc
++] = pt
->p_symtab
;
2786 if (P
== NULL
&& pt
->p_dynsym
!= NULL
)
2787 gsts
[gstc
++] = pt
->p_dynsym
;
2790 * Loop through our array attempting to match the address. If we match
2791 * and we're in exact mode, we're done. Otherwise save the symbol in
2792 * the local sym variable if it is closer than our previous match.
2793 * We explicitly watch for zero-valued symbols since DevPro insists
2794 * on storing __fsr_init_value's value as the symbol value instead
2795 * of storing it in a constant integer.
2797 for (i
= 0; i
< gstc
; i
++) {
2798 if (mdb_gelf_symtab_lookup_by_addr(gsts
[i
], addr
, flags
, buf
,
2799 nbytes
, symp
, &sip
->sym_id
) != 0 || symp
->st_value
== 0)
2802 if (flags
& MDB_TGT_SYM_EXACT
) {
2807 if (gst
== NULL
|| mdb_gelf_sym_closer(symp
, &sym
, addr
)) {
2814 * If we have no libproc handle active, we're done: fail if gst is
2815 * NULL; otherwise copy out our best symbol and skip to the end.
2816 * We also skip to found if gst is the private symbol table: we
2817 * want this to always take precedence over PLT re-vectoring.
2819 if (P
== NULL
|| (gst
!= NULL
&& gst
== mdb
.m_prsym
)) {
2821 return (set_errno(EMDB_NOSYMADDR
));
2827 * Check to see if the address is in a PLT: if it is, use librtld_db to
2828 * attempt to resolve the PLT entry. If the entry is bound, reset addr
2829 * to the bound address, add a special prefix to the caller's buf,
2830 * forget our previous guess, and then continue using the new addr.
2831 * If the entry is not bound, copy the corresponding symbol name into
2832 * buf and return a fake symbol for the given address.
2834 if ((pltsym
= Ppltdest(P
, addr
)) != NULL
) {
2835 const rd_loadobj_t
*rlp
;
2838 if ((rap
= Prd_agent(P
)) != NULL
&&
2839 (rlp
= Paddr_to_loadobj(P
, addr
)) != NULL
&&
2840 rd_plt_resolution(rap
, addr
, Pstatus(P
)->pr_lwp
.pr_lwpid
,
2841 rlp
->rl_plt_base
, &rpi
) == RD_OK
&&
2842 (rpi
.pi_flags
& RD_FLG_PI_PLTBOUND
)) {
2844 n
= mdb_iob_snprintf(buf
, nbytes
, "PLT=");
2845 addr
= rpi
.pi_baddr
;
2855 (void) mdb_iob_snprintf(buf
, nbytes
, "PLT:%s", pltsym
);
2856 bzero(symp
, sizeof (GElf_Sym
));
2857 symp
->st_value
= addr
;
2858 symp
->st_info
= GELF_ST_INFO(STB_GLOBAL
, STT_FUNC
);
2864 * Ask libproc to convert the address to the closest symbol for us.
2865 * Once we get the closest symbol, we perform the EXACT match or
2866 * smart-mode or absolute distance check ourself:
2868 if (PT_LIBPROC_RESOLVE(P
)) {
2869 rv
= Pxlookup_by_addr_resolved(P
, addr
, buf
, nbytes
,
2872 rv
= Pxlookup_by_addr(P
, addr
, buf
, nbytes
,
2875 if ((rv
== 0) && (symp
->st_value
!= 0) &&
2876 (gst
== NULL
|| mdb_gelf_sym_closer(symp
, &sym
, addr
))) {
2878 if (flags
& MDB_TGT_SYM_EXACT
)
2879 match
= (addr
== symp
->st_value
);
2880 else if (mdb
.m_symdist
== 0)
2881 match
= (addr
>= symp
->st_value
&&
2882 addr
< symp
->st_value
+ symp
->st_size
);
2884 match
= (addr
>= symp
->st_value
&&
2885 addr
< symp
->st_value
+ mdb
.m_symdist
);
2888 pmp
= Paddr_to_map(P
, addr
);
2890 sip
->sym_table
= si
.prs_table
;
2891 sip
->sym_id
= si
.prs_id
;
2897 * If we get here, Plookup_by_addr has failed us. If we have no
2898 * previous best symbol (gst == NULL), we've failed completely.
2899 * Otherwise we copy out that symbol and continue on to 'found'.
2902 return (set_errno(EMDB_NOSYMADDR
));
2906 * Once we've found something, copy the final name into the caller's
2907 * buffer and prefix it with the mapping name if appropriate.
2909 if (pmp
!= NULL
&& pmp
!= Pname_to_map(P
, PR_OBJ_EXEC
)) {
2910 const char *prefix
= pmp
->pr_mapname
;
2913 if (PT_LIBPROC_RESOLVE(P
)) {
2914 if (Pobjname_resolved(P
, addr
, pt
->p_objname
,
2916 prefix
= pt
->p_objname
;
2918 if (Pobjname(P
, addr
, pt
->p_objname
, MDB_TGT_MAPSZ
))
2919 prefix
= pt
->p_objname
;
2922 if (buf
!= NULL
&& nbytes
> 1) {
2923 (void) strncpy(pt
->p_symname
, buf
, MDB_TGT_SYM_NAMLEN
);
2924 pt
->p_symname
[MDB_TGT_SYM_NAMLEN
- 1] = '\0';
2926 pt
->p_symname
[0] = '\0';
2929 if (prefix
== pt
->p_objname
&& Plmid(P
, addr
, &lmid
) == 0 && (
2930 (lmid
!= LM_ID_BASE
&& lmid
!= LM_ID_LDSO
) ||
2931 (mdb
.m_flags
& MDB_FL_SHOWLMID
))) {
2932 (void) mdb_iob_snprintf(buf
, nbytes
, "LM%lr`%s`%s",
2933 lmid
, strbasename(prefix
), pt
->p_symname
);
2935 (void) mdb_iob_snprintf(buf
, nbytes
, "%s`%s",
2936 strbasename(prefix
), pt
->p_symname
);
2939 } else if (gst
!= NULL
&& buf
!= NULL
&& nbytes
> 0) {
2940 (void) strncpy(buf
, mdb_gelf_sym_name(gst
, symp
), nbytes
);
2941 buf
[nbytes
- 1] = '\0';
2949 pt_symbol_iter_cb(void *arg
, const GElf_Sym
*sym
, const char *name
,
2950 const prsyminfo_t
*sip
)
2952 pt_symarg_t
*psp
= arg
;
2954 psp
->psym_info
.sym_id
= sip
->prs_id
;
2956 return (psp
->psym_func(psp
->psym_private
, sym
, name
, &psp
->psym_info
,
2961 pt_objsym_iter(void *arg
, const prmap_t
*pmp
, const char *object
)
2963 Lmid_t lmid
= PR_LMID_EVERY
;
2964 pt_symarg_t
*psp
= arg
;
2966 psp
->psym_obj
= object
;
2968 (void) Plmid(psp
->psym_targ
->t_pshandle
, pmp
->pr_vaddr
, &lmid
);
2969 (void) Pxsymbol_iter(psp
->psym_targ
->t_pshandle
, lmid
, object
,
2970 psp
->psym_which
, psp
->psym_type
, pt_symbol_iter_cb
, arg
);
2976 pt_symbol_filt(void *arg
, const GElf_Sym
*sym
, const char *name
, uint_t id
)
2978 pt_symarg_t
*psp
= arg
;
2980 if (mdb_tgt_sym_match(sym
, psp
->psym_type
)) {
2981 psp
->psym_info
.sym_id
= id
;
2982 return (psp
->psym_func(psp
->psym_private
, sym
, name
,
2983 &psp
->psym_info
, psp
->psym_obj
));
2990 pt_symbol_iter(mdb_tgt_t
*t
, const char *object
, uint_t which
,
2991 uint_t type
, mdb_tgt_sym_f
*func
, void *private)
2993 pt_data_t
*pt
= t
->t_data
;
2994 mdb_gelf_symtab_t
*gst
;
2998 object
= pt_resolve_lmid(object
, &lmid
);
3001 ps
.psym_which
= which
;
3002 ps
.psym_type
= type
;
3003 ps
.psym_func
= func
;
3004 ps
.psym_private
= private;
3005 ps
.psym_obj
= object
;
3007 if (t
->t_pshandle
!= NULL
) {
3008 if (object
!= MDB_TGT_OBJ_EVERY
) {
3009 if (Plmid_to_map(t
->t_pshandle
, lmid
, object
) == NULL
)
3010 return (set_errno(EMDB_NOOBJ
));
3011 (void) Pxsymbol_iter(t
->t_pshandle
, lmid
, object
,
3012 which
, type
, pt_symbol_iter_cb
, &ps
);
3014 } else if (Prd_agent(t
->t_pshandle
) != NULL
) {
3015 if (PT_LIBPROC_RESOLVE(t
->t_pshandle
)) {
3016 (void) Pobject_iter_resolved(t
->t_pshandle
,
3017 pt_objsym_iter
, &ps
);
3019 (void) Pobject_iter(t
->t_pshandle
,
3020 pt_objsym_iter
, &ps
);
3026 if (lmid
!= LM_ID_BASE
&& lmid
!= PR_LMID_EVERY
)
3027 return (set_errno(EMDB_NOLMID
));
3029 if (object
!= MDB_TGT_OBJ_EXEC
&& object
!= MDB_TGT_OBJ_EVERY
&&
3030 pt
->p_fio
!= NULL
&&
3031 strcmp(object
, IOP_NAME(pt
->p_fio
)) != 0)
3032 return (set_errno(EMDB_NOOBJ
));
3034 if (which
== MDB_TGT_SYMTAB
)
3040 ps
.psym_info
.sym_table
= gst
->gst_tabid
;
3041 mdb_gelf_symtab_iter(gst
, pt_symbol_filt
, &ps
);
3047 static const mdb_map_t
*
3048 pt_prmap_to_mdbmap(mdb_tgt_t
*t
, const prmap_t
*prp
, mdb_map_t
*mp
)
3050 struct ps_prochandle
*P
= t
->t_pshandle
;
3051 char *rv
, name
[MAXPATHLEN
];
3054 if (PT_LIBPROC_RESOLVE(P
)) {
3055 rv
= Pobjname_resolved(P
, prp
->pr_vaddr
, name
, sizeof (name
));
3057 rv
= Pobjname(P
, prp
->pr_vaddr
, name
, sizeof (name
));
3061 if (Plmid(P
, prp
->pr_vaddr
, &lmid
) == 0 && (
3062 (lmid
!= LM_ID_BASE
&& lmid
!= LM_ID_LDSO
) ||
3063 (mdb
.m_flags
& MDB_FL_SHOWLMID
))) {
3064 (void) mdb_iob_snprintf(mp
->map_name
, MDB_TGT_MAPSZ
,
3065 "LM%lr`%s", lmid
, name
);
3067 (void) strncpy(mp
->map_name
, name
, MDB_TGT_MAPSZ
- 1);
3068 mp
->map_name
[MDB_TGT_MAPSZ
- 1] = '\0';
3071 (void) strncpy(mp
->map_name
, prp
->pr_mapname
,
3073 mp
->map_name
[MDB_TGT_MAPSZ
- 1] = '\0';
3076 mp
->map_base
= prp
->pr_vaddr
;
3077 mp
->map_size
= prp
->pr_size
;
3080 if (prp
->pr_mflags
& MA_READ
)
3081 mp
->map_flags
|= MDB_TGT_MAP_R
;
3082 if (prp
->pr_mflags
& MA_WRITE
)
3083 mp
->map_flags
|= MDB_TGT_MAP_W
;
3084 if (prp
->pr_mflags
& MA_EXEC
)
3085 mp
->map_flags
|= MDB_TGT_MAP_X
;
3087 if (prp
->pr_mflags
& MA_SHM
)
3088 mp
->map_flags
|= MDB_TGT_MAP_SHMEM
;
3089 if (prp
->pr_mflags
& MA_BREAK
)
3090 mp
->map_flags
|= MDB_TGT_MAP_HEAP
;
3091 if (prp
->pr_mflags
& MA_STACK
)
3092 mp
->map_flags
|= MDB_TGT_MAP_STACK
;
3093 if (prp
->pr_mflags
& MA_ANON
)
3094 mp
->map_flags
|= MDB_TGT_MAP_ANON
;
3101 pt_map_apply(void *arg
, const prmap_t
*prp
, const char *name
)
3103 pt_maparg_t
*pmp
= arg
;
3106 return (pmp
->pmap_func(pmp
->pmap_private
,
3107 pt_prmap_to_mdbmap(pmp
->pmap_targ
, prp
, &map
), map
.map_name
));
3111 pt_mapping_iter(mdb_tgt_t
*t
, mdb_tgt_map_f
*func
, void *private)
3113 if (t
->t_pshandle
!= NULL
) {
3117 pm
.pmap_func
= func
;
3118 pm
.pmap_private
= private;
3120 if (PT_LIBPROC_RESOLVE(t
->t_pshandle
)) {
3121 (void) Pmapping_iter_resolved(t
->t_pshandle
,
3124 (void) Pmapping_iter(t
->t_pshandle
,
3130 return (set_errno(EMDB_NOPROC
));
3134 pt_object_iter(mdb_tgt_t
*t
, mdb_tgt_map_f
*func
, void *private)
3136 pt_data_t
*pt
= t
->t_data
;
3139 * If we have a libproc handle, we can just call Pobject_iter to
3140 * iterate over its list of load object information.
3142 if (t
->t_pshandle
!= NULL
) {
3146 pm
.pmap_func
= func
;
3147 pm
.pmap_private
= private;
3149 if (PT_LIBPROC_RESOLVE(t
->t_pshandle
)) {
3150 (void) Pobject_iter_resolved(t
->t_pshandle
,
3153 (void) Pobject_iter(t
->t_pshandle
,
3160 * If we're examining an executable or other ELF file but we have no
3161 * libproc handle, fake up some information based on DT_NEEDED entries.
3163 if (pt
->p_dynsym
!= NULL
&& pt
->p_file
->gf_dyns
!= NULL
&&
3164 pt
->p_fio
!= NULL
) {
3165 mdb_gelf_sect_t
*gsp
= pt
->p_dynsym
->gst_ssect
;
3166 GElf_Dyn
*dynp
= pt
->p_file
->gf_dyns
;
3167 mdb_map_t
*mp
= &pt
->p_map
;
3168 const char *s
= IOP_NAME(pt
->p_fio
);
3171 (void) strncpy(mp
->map_name
, s
, MDB_TGT_MAPSZ
);
3172 mp
->map_name
[MDB_TGT_MAPSZ
- 1] = '\0';
3173 mp
->map_flags
= MDB_TGT_MAP_R
| MDB_TGT_MAP_X
;
3174 mp
->map_base
= NULL
;
3177 if (func(private, mp
, s
) != 0)
3180 for (i
= 0; i
< pt
->p_file
->gf_ndyns
; i
++, dynp
++) {
3181 if (dynp
->d_tag
== DT_NEEDED
) {
3182 s
= (char *)gsp
->gs_data
+ dynp
->d_un
.d_val
;
3183 (void) strncpy(mp
->map_name
, s
, MDB_TGT_MAPSZ
);
3184 mp
->map_name
[MDB_TGT_MAPSZ
- 1] = '\0';
3185 if (func(private, mp
, s
) != 0)
3193 return (set_errno(EMDB_NOPROC
));
3196 static const mdb_map_t
*
3197 pt_addr_to_map(mdb_tgt_t
*t
, uintptr_t addr
)
3199 pt_data_t
*pt
= t
->t_data
;
3202 if (t
->t_pshandle
== NULL
) {
3203 (void) set_errno(EMDB_NOPROC
);
3207 if ((pmp
= Paddr_to_map(t
->t_pshandle
, addr
)) == NULL
) {
3208 (void) set_errno(EMDB_NOMAP
);
3212 return (pt_prmap_to_mdbmap(t
, pmp
, &pt
->p_map
));
3215 static const mdb_map_t
*
3216 pt_name_to_map(mdb_tgt_t
*t
, const char *object
)
3218 pt_data_t
*pt
= t
->t_data
;
3222 if (t
->t_pshandle
== NULL
) {
3223 (void) set_errno(EMDB_NOPROC
);
3227 object
= pt_resolve_lmid(object
, &lmid
);
3229 if ((pmp
= Plmid_to_map(t
->t_pshandle
, lmid
, object
)) == NULL
) {
3230 (void) set_errno(EMDB_NOOBJ
);
3234 return (pt_prmap_to_mdbmap(t
, pmp
, &pt
->p_map
));
3238 pt_addr_to_ctf(mdb_tgt_t
*t
, uintptr_t addr
)
3242 if (t
->t_pshandle
== NULL
) {
3243 (void) set_errno(EMDB_NOPROC
);
3247 if ((ret
= Paddr_to_ctf(t
->t_pshandle
, addr
)) == NULL
) {
3248 (void) set_errno(EMDB_NOOBJ
);
3256 pt_name_to_ctf(mdb_tgt_t
*t
, const char *name
)
3260 if (t
->t_pshandle
== NULL
) {
3261 (void) set_errno(EMDB_NOPROC
);
3265 if ((ret
= Pname_to_ctf(t
->t_pshandle
, name
)) == NULL
) {
3266 (void) set_errno(EMDB_NOOBJ
);
3274 pt_status(mdb_tgt_t
*t
, mdb_tgt_status_t
*tsp
)
3276 const pstatus_t
*psp
;
3280 bzero(tsp
, sizeof (mdb_tgt_status_t
));
3282 if (t
->t_pshandle
== NULL
) {
3283 tsp
->st_state
= MDB_TGT_IDLE
;
3287 switch (state
= Pstate(t
->t_pshandle
)) {
3289 tsp
->st_state
= MDB_TGT_RUNNING
;
3293 tsp
->st_state
= MDB_TGT_STOPPED
;
3294 psp
= Pstatus(t
->t_pshandle
);
3296 tsp
->st_tid
= PTL_TID(t
);
3297 if (PTL_GETREGS(t
, tsp
->st_tid
, gregs
) == 0)
3298 tsp
->st_pc
= gregs
[R_PC
];
3300 if (psp
->pr_flags
& PR_ISTOP
)
3301 tsp
->st_flags
|= MDB_TGT_ISTOP
;
3302 if (psp
->pr_flags
& PR_DSTOP
)
3303 tsp
->st_flags
|= MDB_TGT_DSTOP
;
3308 tsp
->st_state
= MDB_TGT_LOST
;
3311 tsp
->st_state
= MDB_TGT_UNDEAD
;
3314 tsp
->st_state
= MDB_TGT_DEAD
;
3317 tsp
->st_state
= MDB_TGT_IDLE
;
3320 fail("unknown libproc state (%d)\n", state
);
3323 if (t
->t_flags
& MDB_TGT_F_BUSY
)
3324 tsp
->st_flags
|= MDB_TGT_BUSY
;
3330 pt_dupfd(const char *file
, int oflags
, mode_t mode
, int dfd
)
3334 if ((fd
= open(file
, oflags
, mode
)) >= 0) {
3335 (void) fcntl(fd
, F_DUP2FD
, dfd
);
3338 warn("failed to open %s as descriptor %d", file
, dfd
);
3342 * The Pcreate_callback() function interposes on the default, empty libproc
3343 * definition. It will be called following a fork of a new child process by
3344 * Pcreate() below, but before the exec of the new process image. We use this
3345 * callback to optionally redirect stdin and stdout and reset the dispositions
3346 * of SIGPIPE and SIGQUIT from SIG_IGN back to SIG_DFL.
3350 Pcreate_callback(struct ps_prochandle
*P
)
3352 pt_data_t
*pt
= mdb
.m_target
->t_data
;
3354 if (pt
->p_stdin
!= NULL
)
3355 pt_dupfd(pt
->p_stdin
, O_RDWR
, 0, STDIN_FILENO
);
3356 if (pt
->p_stdout
!= NULL
)
3357 pt_dupfd(pt
->p_stdout
, O_CREAT
| O_WRONLY
, 0666, STDOUT_FILENO
);
3359 (void) mdb_signal_sethandler(SIGPIPE
, SIG_DFL
, NULL
);
3360 (void) mdb_signal_sethandler(SIGQUIT
, SIG_DFL
, NULL
);
3364 pt_run(mdb_tgt_t
*t
, int argc
, const mdb_arg_t
*argv
)
3366 pt_data_t
*pt
= t
->t_data
;
3367 struct ps_prochandle
*P
;
3368 char execname
[MAXPATHLEN
];
3375 if (pt
->p_aout_fio
== NULL
) {
3376 warn("run requires executable to be specified on "
3378 return (set_errno(EMDB_TGT
));
3381 pargv
= mdb_alloc(sizeof (char *) * (argc
+ 2), UM_SLEEP
);
3382 pargv
[pargc
++] = strbasename(IOP_NAME(pt
->p_aout_fio
));
3384 for (i
= 0; i
< argc
; i
++) {
3385 if (argv
[i
].a_type
!= MDB_TYPE_STRING
) {
3386 mdb_free(pargv
, sizeof (char *) * (argc
+ 2));
3387 return (set_errno(EINVAL
));
3389 if (argv
[i
].a_un
.a_str
[0] == '<')
3390 pt
->p_stdin
= argv
[i
].a_un
.a_str
+ 1;
3391 else if (argv
[i
].a_un
.a_str
[0] == '>')
3392 pt
->p_stdout
= argv
[i
].a_un
.a_str
+ 1;
3394 pargv
[pargc
++] = argv
[i
].a_un
.a_str
;
3396 pargv
[pargc
] = NULL
;
3399 * Since Pcreate() uses execvp() and "." may not be present in $PATH,
3400 * we must manually prepend "./" when the executable is a simple name.
3402 if (strchr(IOP_NAME(pt
->p_aout_fio
), '/') == NULL
) {
3403 (void) snprintf(execname
, sizeof (execname
), "./%s",
3404 IOP_NAME(pt
->p_aout_fio
));
3406 (void) snprintf(execname
, sizeof (execname
), "%s",
3407 IOP_NAME(pt
->p_aout_fio
));
3410 penv
= mdb_alloc((mdb_nv_size(&pt
->p_env
)+ 1) * sizeof (char *),
3412 for (mdb_nv_rewind(&pt
->p_env
), i
= 0;
3413 (v
= mdb_nv_advance(&pt
->p_env
)) != NULL
; i
++)
3414 penv
[i
] = mdb_nv_get_cookie(v
);
3417 P
= Pxcreate(execname
, (char **)pargv
, penv
, &perr
, NULL
, 0);
3418 mdb_free(pargv
, sizeof (char *) * (argc
+ 2));
3419 pt
->p_stdin
= pt
->p_stdout
= NULL
;
3421 mdb_free(penv
, i
* sizeof (char *));
3424 warn("failed to create process: %s\n", Pcreate_error(perr
));
3425 return (set_errno(EMDB_TGT
));
3428 if (t
->t_pshandle
!= NULL
) {
3429 pt_pre_detach(t
, TRUE
);
3430 if (t
->t_pshandle
!= pt
->p_idlehandle
)
3431 Prelease(t
->t_pshandle
, pt
->p_rflags
);
3434 (void) Punsetflags(P
, PR_RLC
); /* make sure run-on-last-close is off */
3435 (void) Psetflags(P
, PR_KLC
); /* kill on last close by debugger */
3436 pt
->p_rflags
= PRELEASE_KILL
; /* kill on debugger Prelease */
3440 pt_activate_common(t
);
3441 (void) mdb_tgt_status(t
, &t
->t_status
);
3442 mdb
.m_flags
|= MDB_FL_VCREATE
;
3448 * Forward a signal to the victim process in order to force it to stop or die.
3449 * Refer to the comments above pt_setrun(), below, for more info.
3453 pt_sigfwd(int sig
, siginfo_t
*sip
, ucontext_t
*ucp
, mdb_tgt_t
*t
)
3455 struct ps_prochandle
*P
= t
->t_pshandle
;
3456 const lwpstatus_t
*psp
= &Pstatus(P
)->pr_lwp
;
3457 pid_t pid
= Pstatus(P
)->pr_pid
;
3460 if (getpgid(pid
) != mdb
.m_pgid
) {
3461 mdb_dprintf(MDB_DBG_TGT
, "fwd SIG#%d to %d\n", sig
, (int)pid
);
3462 (void) kill(pid
, sig
);
3465 if (Pwait(P
, 1) == 0 && (psp
->pr_flags
& PR_STOPPED
) &&
3466 psp
->pr_why
== PR_JOBCONTROL
&& Pdstop(P
) == 0) {
3468 * If we're job control stopped and our DSTOP is pending, the
3469 * victim will never see our signal, so undo the kill() and
3470 * then send SIGCONT the victim to kick it out of the job
3471 * control stop and force our DSTOP to take effect.
3473 if ((psp
->pr_flags
& PR_DSTOP
) &&
3474 prismember(&Pstatus(P
)->pr_sigpend
, sig
)) {
3477 (void) write(Pctlfd(P
), ctl
, sizeof (ctl
));
3480 mdb_dprintf(MDB_DBG_TGT
, "fwd SIGCONT to %d\n", (int)pid
);
3481 (void) kill(pid
, SIGCONT
);
3486 * Common code for step and continue: if no victim process has been created,
3487 * call pt_run() to create one. Then set the victim running, clearing any
3488 * pending fault. One special case is that if the victim was previously
3489 * stopped on reception of SIGINT, we know that SIGINT was traced and the user
3490 * requested the victim to stop, so clear this signal before continuing.
3491 * For all other traced signals, the signal will be delivered on continue.
3493 * Once the victim process is running, we wait for it to stop on an event of
3494 * interest. Although libproc provides the basic primitive to wait for the
3495 * victim, we must be careful in our handling of signals. We want to allow the
3496 * user to issue a SIGINT or SIGQUIT using the designated terminal control
3497 * character (typically ^C and ^\), and have these signals stop the target and
3498 * return control to the debugger if the signals are traced. There are three
3499 * cases to be considered in our implementation:
3501 * (1) If the debugger and victim are in the same process group, both receive
3502 * the signal from the terminal driver. The debugger returns from Pwait() with
3503 * errno = EINTR, so we want to loop back and continue waiting until the victim
3504 * stops on receipt of its SIGINT or SIGQUIT.
3506 * (2) If the debugger and victim are in different process groups, and the
3507 * victim is a member of the foreground process group, it will receive the
3508 * signal from the terminal driver and the debugger will not. As such, we
3509 * will remain blocked in Pwait() until the victim stops on its signal.
3511 * (3) If the debugger and victim are in different process groups, and the
3512 * debugger is a member of the foreground process group, it will receive the
3513 * signal from the terminal driver, and the victim will not. The debugger
3514 * returns from Pwait() with errno = EINTR, so we need to forward the signal
3515 * to the victim process directly and then Pwait() again for it to stop.
3517 * We can observe that all three cases are handled by simply calling Pwait()
3518 * repeatedly if it fails with EINTR, and forwarding SIGINT and SIGQUIT to
3519 * the victim if it is in a different process group, using pt_sigfwd() above.
3521 * An additional complication is that the process may not be able to field
3522 * the signal if it is currently stopped by job control. In this case, we
3523 * also DSTOP the process, and then send it a SIGCONT to wake it up from
3524 * job control and force it to re-enter stop() under the control of /proc.
3526 * Finally, we would like to allow the user to suspend the process using the
3527 * terminal suspend character (typically ^Z) if both are in the same session.
3528 * We again employ pt_sigfwd() to forward SIGTSTP to the victim, wait for it to
3529 * stop from job control, and then capture it using /proc. Once the process
3530 * has stopped, normal SIGTSTP processing is restored and the user can issue
3531 * another ^Z in order to suspend the debugger and return to the parent shell.
3534 pt_setrun(mdb_tgt_t
*t
, mdb_tgt_status_t
*tsp
, int flags
)
3536 struct ps_prochandle
*P
= t
->t_pshandle
;
3537 pt_data_t
*pt
= t
->t_data
;
3538 pid_t old_pgid
= -1;
3540 mdb_signal_f
*intf
, *quitf
, *tstpf
;
3541 const lwpstatus_t
*psp
;
3542 void *intd
, *quitd
, *tstpd
;
3544 int sig
= pt
->p_signal
;
3548 pt
->p_signal
= 0; /* clear pending signal */
3550 if (P
== NULL
&& pt_run(t
, 0, NULL
) == -1)
3551 return (-1); /* errno is set for us */
3554 psp
= &Pstatus(P
)->pr_lwp
;
3556 if (sig
== 0 && psp
->pr_why
== PR_SIGNALLED
&& psp
->pr_what
== SIGINT
)
3557 flags
|= PRCSIG
; /* clear pending SIGINT */
3559 flags
|= PRCFAULT
; /* clear any pending fault (e.g. BPT) */
3561 intf
= mdb_signal_gethandler(SIGINT
, &intd
);
3562 quitf
= mdb_signal_gethandler(SIGQUIT
, &quitd
);
3563 tstpf
= mdb_signal_gethandler(SIGTSTP
, &tstpd
);
3565 (void) mdb_signal_sethandler(SIGINT
, (mdb_signal_f
*)pt_sigfwd
, t
);
3566 (void) mdb_signal_sethandler(SIGQUIT
, (mdb_signal_f
*)pt_sigfwd
, t
);
3567 (void) mdb_signal_sethandler(SIGTSTP
, (mdb_signal_f
*)pt_sigfwd
, t
);
3569 if (sig
!= 0 && Pstate(P
) == PS_RUN
&&
3570 kill(Pstatus(P
)->pr_pid
, sig
) == -1) {
3576 * If we attached to a job stopped background process in the same
3577 * session, make its pgid the foreground process group before running
3578 * it. Ignore SIGTTOU while doing this to avoid being suspended.
3580 if (mdb
.m_flags
& MDB_FL_JOBCTL
) {
3581 (void) mdb_signal_sethandler(SIGTTOU
, SIG_IGN
, NULL
);
3582 (void) IOP_CTL(mdb
.m_term
, TIOCGPGRP
, &old_pgid
);
3583 (void) IOP_CTL(mdb
.m_term
, TIOCSPGRP
,
3584 (void *)&Pstatus(P
)->pr_pgid
);
3585 (void) mdb_signal_sethandler(SIGTTOU
, SIG_DFL
, NULL
);
3588 if (Pstate(P
) != PS_RUN
&& Psetrun(P
, sig
, flags
) == -1) {
3594 * If the process is stopped on job control, resume its process group
3595 * by sending it a SIGCONT if we are in the same session. Otherwise
3596 * we have no choice but to wait for someone else to foreground it.
3598 if (psp
->pr_why
== PR_JOBCONTROL
) {
3599 if (mdb
.m_flags
& MDB_FL_JOBCTL
)
3600 (void) kill(-Pstatus(P
)->pr_pgid
, SIGCONT
);
3601 else if (mdb
.m_term
!= NULL
)
3602 warn("process is still suspended by job control ...\n");
3606 * Wait for the process to stop. As described above, we loop around if
3607 * we are interrupted (EINTR). If we lose control, attempt to re-open
3608 * the process, or call pt_exec() if that fails to handle a re-exec.
3609 * If the process dies (ENOENT) or Pwait() fails, break out of the loop.
3611 while (Pwait(P
, 0) == -1) {
3612 if (errno
!= EINTR
) {
3613 if (Pstate(P
) == PS_LOST
) {
3614 if (Preopen(P
) == 0)
3615 continue; /* Pwait() again */
3617 pt_exec(t
, 0, NULL
);
3618 } else if (errno
!= ENOENT
)
3619 warn("failed to wait for event");
3625 * If we changed the foreground process group, restore the old pgid
3626 * while ignoring SIGTTOU so we are not accidentally suspended.
3628 if (old_pgid
!= -1) {
3629 (void) mdb_signal_sethandler(SIGTTOU
, SIG_IGN
, NULL
);
3630 (void) IOP_CTL(mdb
.m_term
, TIOCSPGRP
, &pgid
);
3631 (void) mdb_signal_sethandler(SIGTTOU
, SIG_DFL
, NULL
);
3635 * If we're now stopped on exit from a successful exec, release any
3636 * vfork parents and clean out their address space before returning
3637 * to tgt_continue() and perturbing the list of armed event specs.
3638 * If we're stopped for any other reason, just update the mappings.
3640 switch (Pstate(P
)) {
3642 if (psp
->pr_why
== PR_SYSEXIT
&& psp
->pr_errno
== 0 &&
3643 psp
->pr_what
== SYS_execve
)
3644 pt_release_parents(t
);
3651 pt_release_parents(t
);
3656 (void) mdb_signal_sethandler(SIGINT
, intf
, intd
);
3657 (void) mdb_signal_sethandler(SIGQUIT
, quitf
, quitd
);
3658 (void) mdb_signal_sethandler(SIGTSTP
, tstpf
, tstpd
);
3659 (void) pt_status(t
, tsp
);
3661 return (error
? set_errno(error
) : 0);
3665 pt_step(mdb_tgt_t
*t
, mdb_tgt_status_t
*tsp
)
3667 return (pt_setrun(t
, tsp
, PRSTEP
));
3671 pt_continue(mdb_tgt_t
*t
, mdb_tgt_status_t
*tsp
)
3673 return (pt_setrun(t
, tsp
, 0));
3677 pt_signal(mdb_tgt_t
*t
, int sig
)
3679 pt_data_t
*pt
= t
->t_data
;
3681 if (sig
> 0 && sig
<= pt
->p_maxsig
) {
3682 pt
->p_signal
= sig
; /* pending until next pt_setrun */
3686 return (set_errno(EMDB_BADSIGNUM
));
3690 pt_sysenter_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
3692 struct ps_prochandle
*P
= t
->t_pshandle
;
3694 if (P
!= NULL
&& Pstate(P
) < PS_LOST
) {
3695 sep
->se_data
= args
; /* data is raw system call number */
3696 return (Psysentry(P
, (intptr_t)args
, TRUE
) < 0 ? -1 : 0);
3699 return (set_errno(EMDB_NOPROC
));
3703 pt_sysenter_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
3705 (void) Psysentry(t
->t_pshandle
, (intptr_t)sep
->se_data
, FALSE
);
3710 pt_sysenter_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
3711 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
3717 sysnum
= (intptr_t)vep
->ve_args
;
3719 sysnum
= (intptr_t)sep
->se_data
;
3721 (void) proc_sysname(sysnum
, name
, sizeof (name
));
3722 (void) mdb_iob_snprintf(buf
, nbytes
, "stop on entry to %s", name
);
3729 pt_sysenter_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
3731 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
3732 int sysnum
= (intptr_t)sep
->se_data
;
3734 return (psp
->pr_why
== PR_SYSENTRY
&& psp
->pr_what
== sysnum
);
3737 static const mdb_se_ops_t proc_sysenter_ops
= {
3738 pt_sysenter_ctor
, /* se_ctor */
3739 pt_sysenter_dtor
, /* se_dtor */
3740 pt_sysenter_info
, /* se_info */
3741 no_se_secmp
, /* se_secmp */
3742 no_se_vecmp
, /* se_vecmp */
3743 no_se_arm
, /* se_arm */
3744 no_se_disarm
, /* se_disarm */
3745 no_se_cont
, /* se_cont */
3746 pt_sysenter_match
/* se_match */
3750 pt_sysexit_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
3752 struct ps_prochandle
*P
= t
->t_pshandle
;
3754 if (P
!= NULL
&& Pstate(P
) < PS_LOST
) {
3755 sep
->se_data
= args
; /* data is raw system call number */
3756 return (Psysexit(P
, (intptr_t)args
, TRUE
) < 0 ? -1 : 0);
3759 return (set_errno(EMDB_NOPROC
));
3763 pt_sysexit_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
3765 (void) Psysexit(t
->t_pshandle
, (intptr_t)sep
->se_data
, FALSE
);
3770 pt_sysexit_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
3771 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
3777 sysnum
= (intptr_t)vep
->ve_args
;
3779 sysnum
= (intptr_t)sep
->se_data
;
3781 (void) proc_sysname(sysnum
, name
, sizeof (name
));
3782 (void) mdb_iob_snprintf(buf
, nbytes
, "stop on exit from %s", name
);
3789 pt_sysexit_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
3791 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
3792 int sysnum
= (intptr_t)sep
->se_data
;
3794 return (psp
->pr_why
== PR_SYSEXIT
&& psp
->pr_what
== sysnum
);
3797 static const mdb_se_ops_t proc_sysexit_ops
= {
3798 pt_sysexit_ctor
, /* se_ctor */
3799 pt_sysexit_dtor
, /* se_dtor */
3800 pt_sysexit_info
, /* se_info */
3801 no_se_secmp
, /* se_secmp */
3802 no_se_vecmp
, /* se_vecmp */
3803 no_se_arm
, /* se_arm */
3804 no_se_disarm
, /* se_disarm */
3805 no_se_cont
, /* se_cont */
3806 pt_sysexit_match
/* se_match */
3810 pt_signal_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
3812 struct ps_prochandle
*P
= t
->t_pshandle
;
3814 if (P
!= NULL
&& Pstate(P
) < PS_LOST
) {
3815 sep
->se_data
= args
; /* data is raw signal number */
3816 return (Psignal(P
, (intptr_t)args
, TRUE
) < 0 ? -1 : 0);
3819 return (set_errno(EMDB_NOPROC
));
3823 pt_signal_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
3825 (void) Psignal(t
->t_pshandle
, (intptr_t)sep
->se_data
, FALSE
);
3830 pt_signal_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
3831 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
3833 char name
[SIG2STR_MAX
];
3837 signum
= (intptr_t)vep
->ve_args
;
3839 signum
= (intptr_t)sep
->se_data
;
3841 (void) proc_signame(signum
, name
, sizeof (name
));
3842 (void) mdb_iob_snprintf(buf
, nbytes
, "stop on %s", name
);
3849 pt_signal_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
3851 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
3852 int signum
= (intptr_t)sep
->se_data
;
3854 return (psp
->pr_why
== PR_SIGNALLED
&& psp
->pr_what
== signum
);
3857 static const mdb_se_ops_t proc_signal_ops
= {
3858 pt_signal_ctor
, /* se_ctor */
3859 pt_signal_dtor
, /* se_dtor */
3860 pt_signal_info
, /* se_info */
3861 no_se_secmp
, /* se_secmp */
3862 no_se_vecmp
, /* se_vecmp */
3863 no_se_arm
, /* se_arm */
3864 no_se_disarm
, /* se_disarm */
3865 no_se_cont
, /* se_cont */
3866 pt_signal_match
/* se_match */
3870 pt_fault_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
3872 struct ps_prochandle
*P
= t
->t_pshandle
;
3874 if (P
!= NULL
&& Pstate(P
) < PS_LOST
) {
3875 sep
->se_data
= args
; /* data is raw fault number */
3876 return (Pfault(P
, (intptr_t)args
, TRUE
) < 0 ? -1 : 0);
3879 return (set_errno(EMDB_NOPROC
));
3883 pt_fault_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
3885 int fault
= (intptr_t)sep
->se_data
;
3887 if (fault
!= FLTBPT
&& fault
!= FLTTRACE
&& fault
!= FLTWATCH
)
3888 (void) Pfault(t
->t_pshandle
, fault
, FALSE
);
3893 pt_fault_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
3894 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
3900 fltnum
= (intptr_t)vep
->ve_args
;
3902 fltnum
= (intptr_t)sep
->se_data
;
3904 (void) proc_fltname(fltnum
, name
, sizeof (name
));
3905 (void) mdb_iob_snprintf(buf
, nbytes
, "stop on %s", name
);
3912 pt_fault_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
3914 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
3915 int fltnum
= (intptr_t)sep
->se_data
;
3917 return (psp
->pr_why
== PR_FAULTED
&& psp
->pr_what
== fltnum
);
3920 static const mdb_se_ops_t proc_fault_ops
= {
3921 pt_fault_ctor
, /* se_ctor */
3922 pt_fault_dtor
, /* se_dtor */
3923 pt_fault_info
, /* se_info */
3924 no_se_secmp
, /* se_secmp */
3925 no_se_vecmp
, /* se_vecmp */
3926 no_se_arm
, /* se_arm */
3927 no_se_disarm
, /* se_disarm */
3928 no_se_cont
, /* se_cont */
3929 pt_fault_match
/* se_match */
3933 * Callback for pt_ignore() dcmd above: for each VID, determine if it
3934 * corresponds to a vespec that traces the specified signal, and delete it.
3938 pt_ignore_sig(mdb_tgt_t
*t
, void *sig
, int vid
, void *data
)
3940 mdb_vespec_t
*vep
= mdb_tgt_vespec_lookup(t
, vid
);
3942 if (vep
->ve_se
->se_ops
== &proc_signal_ops
&& vep
->ve_args
== sig
)
3943 (void) mdb_tgt_vespec_delete(t
, vid
);
3949 pt_brkpt_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
3951 pt_data_t
*pt
= t
->t_data
;
3952 pt_bparg_t
*pta
= args
;
3956 if (t
->t_pshandle
== NULL
|| Pstate(t
->t_pshandle
) >= PS_LOST
)
3957 return (set_errno(EMDB_NOPROC
));
3959 if (pta
->pta_symbol
!= NULL
) {
3960 if (!pt
->p_rtld_finished
&&
3961 strchr(pta
->pta_symbol
, '`') == NULL
)
3962 return (set_errno(EMDB_NOSYM
));
3963 if (mdb_tgt_lookup_by_scope(t
, pta
->pta_symbol
, &s
,
3965 if (errno
!= EMDB_NOOBJ
&& !(errno
== EMDB_NOSYM
&&
3966 (!(mdb
.m_flags
& MDB_FL_BPTNOSYMSTOP
) ||
3967 !pt
->p_rtld_finished
))) {
3968 warn("breakpoint %s activation failed",
3971 return (-1); /* errno is set for us */
3974 pta
->pta_addr
= (uintptr_t)s
.st_value
;
3978 if (pta
->pta_addr
& 3)
3979 return (set_errno(EMDB_BPALIGN
));
3982 if (Paddr_to_map(t
->t_pshandle
, pta
->pta_addr
) == NULL
)
3983 return (set_errno(EMDB_NOMAP
));
3985 ptb
= mdb_alloc(sizeof (pt_brkpt_t
), UM_SLEEP
);
3986 ptb
->ptb_addr
= pta
->pta_addr
;
3987 ptb
->ptb_instr
= NULL
;
3995 pt_brkpt_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
3997 mdb_free(sep
->se_data
, sizeof (pt_brkpt_t
));
4002 pt_brkpt_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
4003 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
4005 uintptr_t addr
= NULL
;
4008 pt_bparg_t
*pta
= vep
->ve_args
;
4010 if (pta
->pta_symbol
!= NULL
) {
4011 (void) mdb_iob_snprintf(buf
, nbytes
, "stop at %s",
4014 (void) mdb_iob_snprintf(buf
, nbytes
, "stop at %a",
4016 addr
= pta
->pta_addr
;
4020 addr
= ((pt_brkpt_t
*)sep
->se_data
)->ptb_addr
;
4021 (void) mdb_iob_snprintf(buf
, nbytes
, "stop at %a", addr
);
4024 sp
->spec_base
= addr
;
4025 sp
->spec_size
= sizeof (instr_t
);
4031 pt_brkpt_secmp(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
4033 pt_brkpt_t
*ptb
= sep
->se_data
;
4034 pt_bparg_t
*pta
= args
;
4037 if (pta
->pta_symbol
!= NULL
) {
4038 return (mdb_tgt_lookup_by_scope(t
, pta
->pta_symbol
,
4039 &sym
, NULL
) == 0 && sym
.st_value
== ptb
->ptb_addr
);
4042 return (pta
->pta_addr
== ptb
->ptb_addr
);
4047 pt_brkpt_vecmp(mdb_tgt_t
*t
, mdb_vespec_t
*vep
, void *args
)
4049 pt_bparg_t
*pta1
= vep
->ve_args
;
4050 pt_bparg_t
*pta2
= args
;
4052 if (pta1
->pta_symbol
!= NULL
&& pta2
->pta_symbol
!= NULL
)
4053 return (strcmp(pta1
->pta_symbol
, pta2
->pta_symbol
) == 0);
4055 if (pta1
->pta_symbol
== NULL
&& pta2
->pta_symbol
== NULL
)
4056 return (pta1
->pta_addr
== pta2
->pta_addr
);
4058 return (0); /* fail if one is symbolic, other is an explicit address */
4062 pt_brkpt_arm(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
4064 pt_brkpt_t
*ptb
= sep
->se_data
;
4065 return (Psetbkpt(t
->t_pshandle
, ptb
->ptb_addr
, &ptb
->ptb_instr
));
4069 * In order to disarm a breakpoint, we replace the trap instruction at ptb_addr
4070 * with the saved instruction. However, if we have stopped after a successful
4071 * exec(2), we do not want to restore ptb_instr because the address space has
4072 * now been replaced with the text of a different executable, and so restoring
4073 * the saved instruction would be incorrect. The exec itself has effectively
4074 * removed all breakpoint trap instructions for us, so we can just return.
4077 pt_brkpt_disarm(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
4079 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
4080 pt_brkpt_t
*ptb
= sep
->se_data
;
4082 if (psp
->pr_why
== PR_SYSEXIT
&& psp
->pr_errno
== 0 &&
4083 psp
->pr_what
== SYS_execve
)
4084 return (0); /* do not restore saved instruction */
4086 return (Pdelbkpt(t
->t_pshandle
, ptb
->ptb_addr
, ptb
->ptb_instr
));
4090 * Determine whether the specified sespec is an armed watchpoint that overlaps
4091 * with the given breakpoint and has the given flags set. We use this to find
4092 * conflicts with breakpoints, below.
4095 pt_wp_overlap(mdb_sespec_t
*sep
, pt_brkpt_t
*ptb
, int flags
)
4097 const prwatch_t
*wp
= sep
->se_data
;
4099 return (sep
->se_state
== MDB_TGT_SPEC_ARMED
&&
4100 sep
->se_ops
== &proc_wapt_ops
&& (wp
->pr_wflags
& flags
) &&
4101 ptb
->ptb_addr
- wp
->pr_vaddr
< wp
->pr_size
);
4105 * We step over breakpoints using Pxecbkpt() in libproc. If a conflicting
4106 * watchpoint is present, we must temporarily remove it before stepping over
4107 * the breakpoint so we do not immediately re-trigger the watchpoint. We know
4108 * the watchpoint has already triggered on our trap instruction as part of
4109 * fetching it. Before we return, we must re-install any disabled watchpoints.
4112 pt_brkpt_cont(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
4114 pt_brkpt_t
*ptb
= sep
->se_data
;
4117 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
4120 * If the PC no longer matches our original address, then the user has
4121 * changed it while we have been stopped. In this case, it no longer
4122 * makes any sense to continue over this breakpoint. We return as if we
4123 * continued normally.
4125 if ((uintptr_t)psp
->pr_info
.si_addr
!= psp
->pr_reg
[R_PC
])
4126 return (pt_status(t
, tsp
));
4128 for (sep
= mdb_list_next(&t
->t_active
); sep
; sep
= mdb_list_next(sep
)) {
4129 if (pt_wp_overlap(sep
, ptb
, WA_EXEC
))
4130 (void) Pdelwapt(t
->t_pshandle
, sep
->se_data
);
4133 if (Pxecbkpt(t
->t_pshandle
, ptb
->ptb_instr
) == 0 &&
4134 Pdelbkpt(t
->t_pshandle
, ptb
->ptb_addr
, ptb
->ptb_instr
) == 0)
4135 status
= pt_status(t
, tsp
);
4137 error
= errno
; /* save errno from Pxecbkpt, Pdelbkpt, or pt_status */
4139 for (sep
= mdb_list_next(&t
->t_active
); sep
; sep
= mdb_list_next(sep
)) {
4140 if (pt_wp_overlap(sep
, ptb
, WA_EXEC
) &&
4141 Psetwapt(t
->t_pshandle
, sep
->se_data
) == -1) {
4142 sep
->se_state
= MDB_TGT_SPEC_ERROR
;
4143 sep
->se_errno
= errno
;
4147 (void) set_errno(error
);
4153 pt_brkpt_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
4155 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
4156 pt_brkpt_t
*ptb
= sep
->se_data
;
4158 return (psp
->pr_why
== PR_FAULTED
&& psp
->pr_what
== FLTBPT
&&
4159 psp
->pr_reg
[R_PC
] == ptb
->ptb_addr
);
4162 static const mdb_se_ops_t proc_brkpt_ops
= {
4163 pt_brkpt_ctor
, /* se_ctor */
4164 pt_brkpt_dtor
, /* se_dtor */
4165 pt_brkpt_info
, /* se_info */
4166 pt_brkpt_secmp
, /* se_secmp */
4167 pt_brkpt_vecmp
, /* se_vecmp */
4168 pt_brkpt_arm
, /* se_arm */
4169 pt_brkpt_disarm
, /* se_disarm */
4170 pt_brkpt_cont
, /* se_cont */
4171 pt_brkpt_match
/* se_match */
4175 pt_wapt_ctor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
4177 if (t
->t_pshandle
== NULL
|| Pstate(t
->t_pshandle
) >= PS_LOST
)
4178 return (set_errno(EMDB_NOPROC
));
4180 sep
->se_data
= mdb_alloc(sizeof (prwatch_t
), UM_SLEEP
);
4181 bcopy(args
, sep
->se_data
, sizeof (prwatch_t
));
4187 pt_wapt_dtor(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
4189 mdb_free(sep
->se_data
, sizeof (prwatch_t
));
4194 pt_wapt_info(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_vespec_t
*vep
,
4195 mdb_tgt_spec_desc_t
*sp
, char *buf
, size_t nbytes
)
4197 prwatch_t
*wp
= vep
!= NULL
? vep
->ve_args
: sep
->se_data
;
4200 ASSERT(wp
->pr_wflags
!= 0);
4203 switch (wp
->pr_wflags
) {
4205 (void) strcat(desc
, "/read");
4208 (void) strcat(desc
, "/write");
4211 (void) strcat(desc
, "/exec");
4214 if (wp
->pr_wflags
& WA_READ
)
4215 (void) strcat(desc
, "/r");
4216 if (wp
->pr_wflags
& WA_WRITE
)
4217 (void) strcat(desc
, "/w");
4218 if (wp
->pr_wflags
& WA_EXEC
)
4219 (void) strcat(desc
, "/x");
4222 (void) mdb_iob_snprintf(buf
, nbytes
, "stop on %s of [%la, %la)",
4223 desc
+ 1, wp
->pr_vaddr
, wp
->pr_vaddr
+ wp
->pr_size
);
4225 sp
->spec_base
= wp
->pr_vaddr
;
4226 sp
->spec_size
= wp
->pr_size
;
4233 pt_wapt_secmp(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, void *args
)
4235 prwatch_t
*wp1
= sep
->se_data
;
4236 prwatch_t
*wp2
= args
;
4238 return (wp1
->pr_vaddr
== wp2
->pr_vaddr
&&
4239 wp1
->pr_size
== wp2
->pr_size
&& wp1
->pr_wflags
== wp2
->pr_wflags
);
4244 pt_wapt_vecmp(mdb_tgt_t
*t
, mdb_vespec_t
*vep
, void *args
)
4246 prwatch_t
*wp1
= vep
->ve_args
;
4247 prwatch_t
*wp2
= args
;
4249 return (wp1
->pr_vaddr
== wp2
->pr_vaddr
&&
4250 wp1
->pr_size
== wp2
->pr_size
&& wp1
->pr_wflags
== wp2
->pr_wflags
);
4254 pt_wapt_arm(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
4256 return (Psetwapt(t
->t_pshandle
, sep
->se_data
));
4260 pt_wapt_disarm(mdb_tgt_t
*t
, mdb_sespec_t
*sep
)
4262 return (Pdelwapt(t
->t_pshandle
, sep
->se_data
));
4266 * Determine whether the specified sespec is an armed breakpoint at the
4267 * given %pc. We use this to find conflicts with watchpoints below.
4270 pt_bp_overlap(mdb_sespec_t
*sep
, uintptr_t pc
)
4272 pt_brkpt_t
*ptb
= sep
->se_data
;
4274 return (sep
->se_state
== MDB_TGT_SPEC_ARMED
&&
4275 sep
->se_ops
== &proc_brkpt_ops
&& ptb
->ptb_addr
== pc
);
4279 * We step over watchpoints using Pxecwapt() in libproc. If a conflicting
4280 * breakpoint is present, we must temporarily disarm it before stepping
4281 * over the watchpoint so we do not immediately re-trigger the breakpoint.
4282 * This is similar to the case handled in pt_brkpt_cont(), above.
4285 pt_wapt_cont(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
4287 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
4288 mdb_sespec_t
*bep
= NULL
;
4293 * If the PC no longer matches our original address, then the user has
4294 * changed it while we have been stopped. In this case, it no longer
4295 * makes any sense to continue over this instruction. We return as if
4296 * we continued normally.
4298 if ((uintptr_t)psp
->pr_info
.si_pc
!= psp
->pr_reg
[R_PC
])
4299 return (pt_status(t
, tsp
));
4301 if (psp
->pr_info
.si_code
!= TRAP_XWATCH
) {
4302 for (bep
= mdb_list_next(&t
->t_active
); bep
!= NULL
;
4303 bep
= mdb_list_next(bep
)) {
4304 if (pt_bp_overlap(bep
, psp
->pr_reg
[R_PC
])) {
4305 (void) bep
->se_ops
->se_disarm(t
, bep
);
4306 bep
->se_state
= MDB_TGT_SPEC_ACTIVE
;
4312 if (Pxecwapt(t
->t_pshandle
, sep
->se_data
) == 0)
4313 status
= pt_status(t
, tsp
);
4315 error
= errno
; /* save errno from Pxecwapt or pt_status */
4318 mdb_tgt_sespec_arm_one(t
, bep
);
4320 (void) set_errno(error
);
4326 pt_wapt_match(mdb_tgt_t
*t
, mdb_sespec_t
*sep
, mdb_tgt_status_t
*tsp
)
4328 const lwpstatus_t
*psp
= &Pstatus(t
->t_pshandle
)->pr_lwp
;
4329 prwatch_t
*wp
= sep
->se_data
;
4331 return (psp
->pr_why
== PR_FAULTED
&& psp
->pr_what
== FLTWATCH
&&
4332 (uintptr_t)psp
->pr_info
.si_addr
- wp
->pr_vaddr
< wp
->pr_size
);
4335 static const mdb_se_ops_t proc_wapt_ops
= {
4336 pt_wapt_ctor
, /* se_ctor */
4337 pt_wapt_dtor
, /* se_dtor */
4338 pt_wapt_info
, /* se_info */
4339 pt_wapt_secmp
, /* se_secmp */
4340 pt_wapt_vecmp
, /* se_vecmp */
4341 pt_wapt_arm
, /* se_arm */
4342 pt_wapt_disarm
, /* se_disarm */
4343 pt_wapt_cont
, /* se_cont */
4344 pt_wapt_match
/* se_match */
4348 pt_bparg_dtor(mdb_vespec_t
*vep
)
4350 pt_bparg_t
*pta
= vep
->ve_args
;
4352 if (pta
->pta_symbol
!= NULL
)
4353 strfree(pta
->pta_symbol
);
4355 mdb_free(pta
, sizeof (pt_bparg_t
));
4359 pt_add_vbrkpt(mdb_tgt_t
*t
, uintptr_t addr
,
4360 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4362 pt_bparg_t
*pta
= mdb_alloc(sizeof (pt_bparg_t
), UM_SLEEP
);
4364 pta
->pta_symbol
= NULL
;
4365 pta
->pta_addr
= addr
;
4367 return (mdb_tgt_vespec_insert(t
, &proc_brkpt_ops
, spec_flags
,
4368 func
, data
, pta
, pt_bparg_dtor
));
4372 pt_add_sbrkpt(mdb_tgt_t
*t
, const char *sym
,
4373 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4377 if (sym
[0] == '`') {
4378 (void) set_errno(EMDB_NOOBJ
);
4382 if (sym
[strlen(sym
) - 1] == '`') {
4383 (void) set_errno(EMDB_NOSYM
);
4387 pta
= mdb_alloc(sizeof (pt_bparg_t
), UM_SLEEP
);
4388 pta
->pta_symbol
= strdup(sym
);
4389 pta
->pta_addr
= NULL
;
4391 return (mdb_tgt_vespec_insert(t
, &proc_brkpt_ops
, spec_flags
,
4392 func
, data
, pta
, pt_bparg_dtor
));
4396 pt_wparg_overlap(const prwatch_t
*wp1
, const prwatch_t
*wp2
)
4398 if (wp2
->pr_vaddr
+ wp2
->pr_size
<= wp1
->pr_vaddr
)
4399 return (0); /* no range overlap */
4401 if (wp1
->pr_vaddr
+ wp1
->pr_size
<= wp2
->pr_vaddr
)
4402 return (0); /* no range overlap */
4404 return (wp1
->pr_vaddr
!= wp2
->pr_vaddr
||
4405 wp1
->pr_size
!= wp2
->pr_size
|| wp1
->pr_wflags
!= wp2
->pr_wflags
);
4409 pt_wparg_dtor(mdb_vespec_t
*vep
)
4411 mdb_free(vep
->ve_args
, sizeof (prwatch_t
));
4415 pt_add_vwapt(mdb_tgt_t
*t
, uintptr_t addr
, size_t len
, uint_t wflags
,
4416 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4418 prwatch_t
*wp
= mdb_alloc(sizeof (prwatch_t
), UM_SLEEP
);
4421 wp
->pr_vaddr
= addr
;
4425 if (wflags
& MDB_TGT_WA_R
)
4426 wp
->pr_wflags
|= WA_READ
;
4427 if (wflags
& MDB_TGT_WA_W
)
4428 wp
->pr_wflags
|= WA_WRITE
;
4429 if (wflags
& MDB_TGT_WA_X
)
4430 wp
->pr_wflags
|= WA_EXEC
;
4432 for (sep
= mdb_list_next(&t
->t_active
); sep
; sep
= mdb_list_next(sep
)) {
4433 if (sep
->se_ops
== &proc_wapt_ops
&&
4434 mdb_list_next(&sep
->se_velist
) != NULL
&&
4435 pt_wparg_overlap(wp
, sep
->se_data
))
4439 for (sep
= mdb_list_next(&t
->t_idle
); sep
; sep
= mdb_list_next(sep
)) {
4440 if (sep
->se_ops
== &proc_wapt_ops
&& pt_wparg_overlap(wp
,
4441 ((mdb_vespec_t
*)mdb_list_next(&sep
->se_velist
))->ve_args
))
4445 return (mdb_tgt_vespec_insert(t
, &proc_wapt_ops
, spec_flags
,
4446 func
, data
, wp
, pt_wparg_dtor
));
4449 mdb_free(wp
, sizeof (prwatch_t
));
4450 (void) set_errno(EMDB_WPDUP
);
4455 pt_add_sysenter(mdb_tgt_t
*t
, int sysnum
,
4456 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4458 if (sysnum
<= 0 || sysnum
> PRMAXSYS
) {
4459 (void) set_errno(EMDB_BADSYSNUM
);
4463 return (mdb_tgt_vespec_insert(t
, &proc_sysenter_ops
, spec_flags
,
4464 func
, data
, (void *)(uintptr_t)sysnum
, no_ve_dtor
));
4468 pt_add_sysexit(mdb_tgt_t
*t
, int sysnum
,
4469 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4471 if (sysnum
<= 0 || sysnum
> PRMAXSYS
) {
4472 (void) set_errno(EMDB_BADSYSNUM
);
4476 return (mdb_tgt_vespec_insert(t
, &proc_sysexit_ops
, spec_flags
,
4477 func
, data
, (void *)(uintptr_t)sysnum
, no_ve_dtor
));
4481 pt_add_signal(mdb_tgt_t
*t
, int signum
,
4482 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4484 pt_data_t
*pt
= t
->t_data
;
4486 if (signum
<= 0 || signum
> pt
->p_maxsig
) {
4487 (void) set_errno(EMDB_BADSIGNUM
);
4491 return (mdb_tgt_vespec_insert(t
, &proc_signal_ops
, spec_flags
,
4492 func
, data
, (void *)(uintptr_t)signum
, no_ve_dtor
));
4496 pt_add_fault(mdb_tgt_t
*t
, int fltnum
,
4497 int spec_flags
, mdb_tgt_se_f
*func
, void *data
)
4499 if (fltnum
<= 0 || fltnum
> PRMAXFAULT
) {
4500 (void) set_errno(EMDB_BADFLTNUM
);
4504 return (mdb_tgt_vespec_insert(t
, &proc_fault_ops
, spec_flags
,
4505 func
, data
, (void *)(uintptr_t)fltnum
, no_ve_dtor
));
4509 pt_getareg(mdb_tgt_t
*t
, mdb_tgt_tid_t tid
,
4510 const char *rname
, mdb_tgt_reg_t
*rp
)
4512 pt_data_t
*pt
= t
->t_data
;
4516 if (t
->t_pshandle
== NULL
)
4517 return (set_errno(EMDB_NOPROC
));
4519 if ((v
= mdb_nv_lookup(&pt
->p_regs
, rname
)) != NULL
) {
4520 uintmax_t rd_nval
= mdb_nv_get_value(v
);
4521 ushort_t rd_num
= MDB_TGT_R_NUM(rd_nval
);
4522 ushort_t rd_flags
= MDB_TGT_R_FLAGS(rd_nval
);
4524 if (!MDB_TGT_R_IS_FP(rd_flags
)) {
4525 mdb_tgt_reg_t r
= 0;
4527 #if defined(__sparc) && defined(_ILP32)
4529 * If we are debugging on 32-bit SPARC, the globals and
4530 * outs can have 32 upper bits hiding in the xregs.
4532 /* gcc doesn't like >= R_G0 because R_G0 == 0 */
4533 int is_g
= (rd_num
== R_G0
||
4534 rd_num
>= R_G1
&& rd_num
<= R_G7
);
4535 int is_o
= (rd_num
>= R_O0
&& rd_num
<= R_O7
);
4538 if (is_g
&& PTL_GETXREGS(t
, tid
, &xrs
) == 0 &&
4539 xrs
.pr_type
== XR_TYPE_V8P
) {
4540 r
|= (uint64_t)xrs
.pr_un
.pr_v8p
.pr_xg
[
4541 rd_num
- R_G0
+ XR_G0
] << 32;
4544 if (is_o
&& PTL_GETXREGS(t
, tid
, &xrs
) == 0 &&
4545 xrs
.pr_type
== XR_TYPE_V8P
) {
4546 r
|= (uint64_t)xrs
.pr_un
.pr_v8p
.pr_xo
[
4547 rd_num
- R_O0
+ XR_O0
] << 32;
4549 #endif /* __sparc && _ILP32 */
4552 * Avoid sign-extension by casting: recall that procfs
4553 * defines prgreg_t as a long or int and our native
4554 * register handling uses uint64_t's.
4556 if (PTL_GETREGS(t
, tid
, grs
) == 0) {
4557 *rp
= r
| (ulong_t
)grs
[rd_num
];
4558 if (rd_flags
& MDB_TGT_R_32
)
4559 *rp
&= 0xffffffffULL
;
4560 else if (rd_flags
& MDB_TGT_R_16
)
4562 else if (rd_flags
& MDB_TGT_R_8H
)
4563 *rp
= (*rp
& 0xff00ULL
) >> 8;
4564 else if (rd_flags
& MDB_TGT_R_8L
)
4570 return (pt_getfpreg(t
, tid
, rd_num
, rd_flags
, rp
));
4573 return (set_errno(EMDB_BADREG
));
4577 pt_putareg(mdb_tgt_t
*t
, mdb_tgt_tid_t tid
, const char *rname
, mdb_tgt_reg_t r
)
4579 pt_data_t
*pt
= t
->t_data
;
4583 if (t
->t_pshandle
== NULL
)
4584 return (set_errno(EMDB_NOPROC
));
4586 if ((v
= mdb_nv_lookup(&pt
->p_regs
, rname
)) != NULL
) {
4587 uintmax_t rd_nval
= mdb_nv_get_value(v
);
4588 ushort_t rd_num
= MDB_TGT_R_NUM(rd_nval
);
4589 ushort_t rd_flags
= MDB_TGT_R_FLAGS(rd_nval
);
4591 if (!MDB_TGT_R_IS_FP(rd_flags
)) {
4593 if (rd_flags
& MDB_TGT_R_32
)
4595 else if (rd_flags
& MDB_TGT_R_16
)
4597 else if (rd_flags
& MDB_TGT_R_8H
)
4598 r
= (r
& 0xffULL
) << 8;
4599 else if (rd_flags
& MDB_TGT_R_8L
)
4602 #if defined(__sparc) && defined(_ILP32)
4604 * If we are debugging on 32-bit SPARC, the globals and
4605 * outs can have 32 upper bits stored in the xregs.
4607 int is_g
= (rd_num
== R_G0
||
4608 rd_num
>= R_G1
&& rd_num
<= R_G7
);
4609 int is_o
= (rd_num
>= R_O0
&& rd_num
<= R_O7
);
4612 if ((is_g
|| is_o
) && PTL_GETXREGS(t
, tid
, &xrs
) == 0 &&
4613 xrs
.pr_type
== XR_TYPE_V8P
) {
4615 xrs
.pr_un
.pr_v8p
.pr_xg
[rd_num
-
4616 R_G0
+ XR_G0
] = (uint32_t)(r
>> 32);
4618 xrs
.pr_un
.pr_v8p
.pr_xo
[rd_num
-
4619 R_O0
+ XR_O0
] = (uint32_t)(r
>> 32);
4622 if (PTL_SETXREGS(t
, tid
, &xrs
) == -1)
4625 #endif /* __sparc && _ILP32 */
4627 if (PTL_GETREGS(t
, tid
, grs
) == 0) {
4628 grs
[rd_num
] = (prgreg_t
)r
;
4629 return (PTL_SETREGS(t
, tid
, grs
));
4633 return (pt_putfpreg(t
, tid
, rd_num
, rd_flags
, r
));
4636 return (set_errno(EMDB_BADREG
));
4640 pt_stack_call(pt_stkarg_t
*psp
, const prgregset_t grs
, uint_t argc
, long *argv
)
4642 psp
->pstk_gotpc
|= (grs
[R_PC
] != 0);
4644 if (!psp
->pstk_gotpc
)
4645 return (0); /* skip initial zeroed frames */
4647 return (psp
->pstk_func(psp
->pstk_private
, grs
[R_PC
],
4648 argc
, argv
, (const struct mdb_tgt_gregset
*)grs
));
4652 pt_stack_iter(mdb_tgt_t
*t
, const mdb_tgt_gregset_t
*gsp
,
4653 mdb_tgt_stack_f
*func
, void *arg
)
4655 if (t
->t_pshandle
!= NULL
) {
4658 pstk
.pstk_func
= func
;
4659 pstk
.pstk_private
= arg
;
4660 pstk
.pstk_gotpc
= FALSE
;
4662 (void) Pstack_iter(t
->t_pshandle
, gsp
->gregs
,
4663 (proc_stack_f
*)pt_stack_call
, &pstk
);
4668 return (set_errno(EMDB_NOPROC
));
4672 pt_auxv(mdb_tgt_t
*t
, const auxv_t
**auxvp
)
4674 if (t
->t_pshandle
!= NULL
) {
4675 *auxvp
= Pgetauxvec(t
->t_pshandle
);
4679 return (set_errno(EMDB_NOPROC
));
4683 static const mdb_tgt_ops_t proc_ops
= {
4684 pt_setflags
, /* t_setflags */
4685 (int (*)()) mdb_tgt_notsup
, /* t_setcontext */
4686 pt_activate
, /* t_activate */
4687 pt_deactivate
, /* t_deactivate */
4688 pt_periodic
, /* t_periodic */
4689 pt_destroy
, /* t_destroy */
4690 pt_name
, /* t_name */
4691 (const char *(*)()) mdb_conf_isa
, /* t_isa */
4692 pt_platform
, /* t_platform */
4693 pt_uname
, /* t_uname */
4694 pt_dmodel
, /* t_dmodel */
4695 (ssize_t (*)()) mdb_tgt_notsup
, /* t_aread */
4696 (ssize_t (*)()) mdb_tgt_notsup
, /* t_awrite */
4697 pt_vread
, /* t_vread */
4698 pt_vwrite
, /* t_vwrite */
4699 (ssize_t (*)()) mdb_tgt_notsup
, /* t_pread */
4700 (ssize_t (*)()) mdb_tgt_notsup
, /* t_pwrite */
4701 pt_fread
, /* t_fread */
4702 pt_fwrite
, /* t_fwrite */
4703 (ssize_t (*)()) mdb_tgt_notsup
, /* t_ioread */
4704 (ssize_t (*)()) mdb_tgt_notsup
, /* t_iowrite */
4705 (int (*)()) mdb_tgt_notsup
, /* t_vtop */
4706 pt_lookup_by_name
, /* t_lookup_by_name */
4707 pt_lookup_by_addr
, /* t_lookup_by_addr */
4708 pt_symbol_iter
, /* t_symbol_iter */
4709 pt_mapping_iter
, /* t_mapping_iter */
4710 pt_object_iter
, /* t_object_iter */
4711 pt_addr_to_map
, /* t_addr_to_map */
4712 pt_name_to_map
, /* t_name_to_map */
4713 pt_addr_to_ctf
, /* t_addr_to_ctf */
4714 pt_name_to_ctf
, /* t_name_to_ctf */
4715 pt_status
, /* t_status */
4717 pt_step
, /* t_step */
4718 pt_step_out
, /* t_step_out */
4719 pt_next
, /* t_next */
4720 pt_continue
, /* t_cont */
4721 pt_signal
, /* t_signal */
4722 pt_add_vbrkpt
, /* t_add_vbrkpt */
4723 pt_add_sbrkpt
, /* t_add_sbrkpt */
4724 (int (*)()) mdb_tgt_null
, /* t_add_pwapt */
4725 pt_add_vwapt
, /* t_add_vwapt */
4726 (int (*)()) mdb_tgt_null
, /* t_add_iowapt */
4727 pt_add_sysenter
, /* t_add_sysenter */
4728 pt_add_sysexit
, /* t_add_sysexit */
4729 pt_add_signal
, /* t_add_signal */
4730 pt_add_fault
, /* t_add_fault */
4731 pt_getareg
, /* t_getareg */
4732 pt_putareg
, /* t_putareg */
4733 pt_stack_iter
, /* t_stack_iter */
4734 pt_auxv
/* t_auxv */
4738 * Utility function for converting libproc errno values to mdb error values
4739 * for the ptl calls below. Currently, we only need to convert ENOENT to
4740 * EMDB_NOTHREAD to produce a more useful error message for the user.
4745 if (error
!= 0 && errno
== ENOENT
)
4746 return (set_errno(EMDB_NOTHREAD
));
4752 static mdb_tgt_tid_t
4753 pt_lwp_tid(mdb_tgt_t
*t
, void *tap
)
4755 if (t
->t_pshandle
!= NULL
)
4756 return (Pstatus(t
->t_pshandle
)->pr_lwp
.pr_lwpid
);
4758 return (set_errno(EMDB_NOPROC
));
4762 pt_lwp_add(mdb_addrvec_t
*ap
, const lwpstatus_t
*psp
)
4764 mdb_addrvec_unshift(ap
, psp
->pr_lwpid
);
4770 pt_lwp_iter(mdb_tgt_t
*t
, void *tap
, mdb_addrvec_t
*ap
)
4772 if (t
->t_pshandle
!= NULL
)
4773 return (Plwp_iter(t
->t_pshandle
, (proc_lwp_f
*)pt_lwp_add
, ap
));
4775 return (set_errno(EMDB_NOPROC
));
4780 pt_lwp_getregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prgregset_t gregs
)
4782 if (t
->t_pshandle
!= NULL
) {
4783 return (ptl_err(Plwp_getregs(t
->t_pshandle
,
4784 (lwpid_t
)tid
, gregs
)));
4786 return (set_errno(EMDB_NOPROC
));
4791 pt_lwp_setregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prgregset_t gregs
)
4793 if (t
->t_pshandle
!= NULL
) {
4794 return (ptl_err(Plwp_setregs(t
->t_pshandle
,
4795 (lwpid_t
)tid
, gregs
)));
4797 return (set_errno(EMDB_NOPROC
));
4804 pt_lwp_getxregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prxregset_t
*xregs
)
4806 if (t
->t_pshandle
!= NULL
) {
4807 return (ptl_err(Plwp_getxregs(t
->t_pshandle
,
4808 (lwpid_t
)tid
, xregs
)));
4810 return (set_errno(EMDB_NOPROC
));
4815 pt_lwp_setxregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
4816 const prxregset_t
*xregs
)
4818 if (t
->t_pshandle
!= NULL
) {
4819 return (ptl_err(Plwp_setxregs(t
->t_pshandle
,
4820 (lwpid_t
)tid
, xregs
)));
4822 return (set_errno(EMDB_NOPROC
));
4825 #endif /* __sparc */
4829 pt_lwp_getfpregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
4830 prfpregset_t
*fpregs
)
4832 if (t
->t_pshandle
!= NULL
) {
4833 return (ptl_err(Plwp_getfpregs(t
->t_pshandle
,
4834 (lwpid_t
)tid
, fpregs
)));
4836 return (set_errno(EMDB_NOPROC
));
4841 pt_lwp_setfpregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
4842 const prfpregset_t
*fpregs
)
4844 if (t
->t_pshandle
!= NULL
) {
4845 return (ptl_err(Plwp_setfpregs(t
->t_pshandle
,
4846 (lwpid_t
)tid
, fpregs
)));
4848 return (set_errno(EMDB_NOPROC
));
4851 static const pt_ptl_ops_t proc_lwp_ops
= {
4852 (int (*)()) mdb_tgt_nop
,
4853 (void (*)()) mdb_tgt_nop
,
4867 pt_tdb_ctor(mdb_tgt_t
*t
)
4869 pt_data_t
*pt
= t
->t_data
;
4873 if ((err
= pt
->p_tdb_ops
->td_ta_new(t
->t_pshandle
, &tap
)) != TD_OK
)
4874 return (set_errno(tdb_to_errno(err
)));
4876 pt
->p_ptl_hdl
= tap
;
4881 pt_tdb_dtor(mdb_tgt_t
*t
, void *tap
)
4883 pt_data_t
*pt
= t
->t_data
;
4885 ASSERT(tap
== pt
->p_ptl_hdl
);
4886 (void) pt
->p_tdb_ops
->td_ta_delete(tap
);
4887 pt
->p_ptl_hdl
= NULL
;
4890 static mdb_tgt_tid_t
4891 pt_tdb_tid(mdb_tgt_t
*t
, void *tap
)
4893 pt_data_t
*pt
= t
->t_data
;
4899 if (t
->t_pshandle
== NULL
)
4900 return (set_errno(EMDB_NOPROC
));
4902 if ((err
= pt
->p_tdb_ops
->td_ta_map_lwp2thr(tap
,
4903 Pstatus(t
->t_pshandle
)->pr_lwp
.pr_lwpid
, &th
)) != TD_OK
)
4904 return (set_errno(tdb_to_errno(err
)));
4906 if ((err
= pt
->p_tdb_ops
->td_thr_get_info(&th
, &ti
)) != TD_OK
)
4907 return (set_errno(tdb_to_errno(err
)));
4913 pt_tdb_add(const td_thrhandle_t
*thp
, pt_addarg_t
*pap
)
4917 if (pap
->pa_pt
->p_tdb_ops
->td_thr_get_info(thp
, &ti
) == TD_OK
&&
4918 ti
.ti_state
!= TD_THR_ZOMBIE
)
4919 mdb_addrvec_unshift(pap
->pa_ap
, ti
.ti_tid
);
4925 pt_tdb_iter(mdb_tgt_t
*t
, void *tap
, mdb_addrvec_t
*ap
)
4927 pt_data_t
*pt
= t
->t_data
;
4931 if (t
->t_pshandle
== NULL
)
4932 return (set_errno(EMDB_NOPROC
));
4937 if ((err
= pt
->p_tdb_ops
->td_ta_thr_iter(tap
, (td_thr_iter_f
*)
4938 pt_tdb_add
, &arg
, TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
4939 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
)) != TD_OK
)
4940 return (set_errno(tdb_to_errno(err
)));
4946 pt_tdb_getregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prgregset_t gregs
)
4948 pt_data_t
*pt
= t
->t_data
;
4953 if (t
->t_pshandle
== NULL
)
4954 return (set_errno(EMDB_NOPROC
));
4956 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
4957 return (set_errno(tdb_to_errno(err
)));
4959 err
= pt
->p_tdb_ops
->td_thr_getgregs(&th
, gregs
);
4960 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
4961 return (set_errno(tdb_to_errno(err
)));
4967 pt_tdb_setregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prgregset_t gregs
)
4969 pt_data_t
*pt
= t
->t_data
;
4974 if (t
->t_pshandle
== NULL
)
4975 return (set_errno(EMDB_NOPROC
));
4977 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
4978 return (set_errno(tdb_to_errno(err
)));
4980 err
= pt
->p_tdb_ops
->td_thr_setgregs(&th
, gregs
);
4981 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
4982 return (set_errno(tdb_to_errno(err
)));
4990 pt_tdb_getxregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
, prxregset_t
*xregs
)
4992 pt_data_t
*pt
= t
->t_data
;
4997 if (t
->t_pshandle
== NULL
)
4998 return (set_errno(EMDB_NOPROC
));
5000 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
5001 return (set_errno(tdb_to_errno(err
)));
5003 err
= pt
->p_tdb_ops
->td_thr_getxregs(&th
, xregs
);
5004 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
5005 return (set_errno(tdb_to_errno(err
)));
5011 pt_tdb_setxregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
5012 const prxregset_t
*xregs
)
5014 pt_data_t
*pt
= t
->t_data
;
5019 if (t
->t_pshandle
== NULL
)
5020 return (set_errno(EMDB_NOPROC
));
5022 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
5023 return (set_errno(tdb_to_errno(err
)));
5025 err
= pt
->p_tdb_ops
->td_thr_setxregs(&th
, xregs
);
5026 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
5027 return (set_errno(tdb_to_errno(err
)));
5032 #endif /* __sparc */
5035 pt_tdb_getfpregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
5036 prfpregset_t
*fpregs
)
5038 pt_data_t
*pt
= t
->t_data
;
5043 if (t
->t_pshandle
== NULL
)
5044 return (set_errno(EMDB_NOPROC
));
5046 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
5047 return (set_errno(tdb_to_errno(err
)));
5049 err
= pt
->p_tdb_ops
->td_thr_getfpregs(&th
, fpregs
);
5050 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
5051 return (set_errno(tdb_to_errno(err
)));
5057 pt_tdb_setfpregs(mdb_tgt_t
*t
, void *tap
, mdb_tgt_tid_t tid
,
5058 const prfpregset_t
*fpregs
)
5060 pt_data_t
*pt
= t
->t_data
;
5065 if (t
->t_pshandle
== NULL
)
5066 return (set_errno(EMDB_NOPROC
));
5068 if ((err
= pt
->p_tdb_ops
->td_ta_map_id2thr(tap
, tid
, &th
)) != TD_OK
)
5069 return (set_errno(tdb_to_errno(err
)));
5071 err
= pt
->p_tdb_ops
->td_thr_setfpregs(&th
, fpregs
);
5072 if (err
!= TD_OK
&& err
!= TD_PARTIALREG
)
5073 return (set_errno(tdb_to_errno(err
)));
5078 static const pt_ptl_ops_t proc_tdb_ops
= {
5094 pt_xd_auxv(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5096 struct ps_prochandle
*P
= t
->t_pshandle
;
5097 const auxv_t
*auxp
, *auxv
= NULL
;
5100 if (P
!= NULL
&& (auxv
= Pgetauxvec(P
)) != NULL
&&
5101 auxv
->a_type
!= AT_NULL
) {
5102 for (auxp
= auxv
, auxn
= 1; auxp
->a_type
!= NULL
; auxp
++)
5106 if (buf
== NULL
&& nbytes
== 0)
5107 return (sizeof (auxv_t
) * auxn
);
5110 return (set_errno(ENODATA
));
5112 nbytes
= MIN(nbytes
, sizeof (auxv_t
) * auxn
);
5113 bcopy(auxv
, buf
, nbytes
);
5118 pt_xd_cred(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5123 if (t
->t_pshandle
!= NULL
&& Pcred(t
->t_pshandle
, &cr
, 1) == 0) {
5124 cbytes
= (cr
.pr_ngroups
<= 1) ? sizeof (prcred_t
) :
5125 (sizeof (prcred_t
) + (cr
.pr_ngroups
- 1) * sizeof (gid_t
));
5128 if (buf
== NULL
&& nbytes
== 0)
5132 return (set_errno(ENODATA
));
5134 crp
= mdb_alloc(cbytes
, UM_SLEEP
);
5136 if (Pcred(t
->t_pshandle
, crp
, cr
.pr_ngroups
) == -1)
5137 return (set_errno(ENODATA
));
5139 nbytes
= MIN(nbytes
, cbytes
);
5140 bcopy(crp
, buf
, nbytes
);
5141 mdb_free(crp
, cbytes
);
5146 pt_xd_ehdr(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5148 pt_data_t
*pt
= t
->t_data
;
5150 if (buf
== NULL
&& nbytes
== 0)
5151 return (sizeof (GElf_Ehdr
));
5153 if (pt
->p_file
== NULL
)
5154 return (set_errno(ENODATA
));
5156 nbytes
= MIN(nbytes
, sizeof (GElf_Ehdr
));
5157 bcopy(&pt
->p_file
->gf_ehdr
, buf
, nbytes
);
5162 pt_copy_lwp(lwpstatus_t
**lspp
, const lwpstatus_t
*lsp
)
5164 bcopy(lsp
, *lspp
, sizeof (lwpstatus_t
));
5170 pt_xd_lwpstatus(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5172 lwpstatus_t
*lsp
, *lbuf
;
5173 const pstatus_t
*psp
;
5176 if (t
->t_pshandle
!= NULL
&& (psp
= Pstatus(t
->t_pshandle
)) != NULL
)
5177 nlwp
= psp
->pr_nlwp
;
5179 if (buf
== NULL
&& nbytes
== 0)
5180 return (sizeof (lwpstatus_t
) * nlwp
);
5183 return (set_errno(ENODATA
));
5185 lsp
= lbuf
= mdb_alloc(sizeof (lwpstatus_t
) * nlwp
, UM_SLEEP
);
5186 nbytes
= MIN(nbytes
, sizeof (lwpstatus_t
) * nlwp
);
5188 (void) Plwp_iter(t
->t_pshandle
, (proc_lwp_f
*)pt_copy_lwp
, &lsp
);
5189 bcopy(lbuf
, buf
, nbytes
);
5191 mdb_free(lbuf
, sizeof (lwpstatus_t
) * nlwp
);
5196 pt_xd_pshandle(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5198 if (buf
== NULL
&& nbytes
== 0)
5199 return (sizeof (struct ps_prochandle
*));
5201 if (t
->t_pshandle
== NULL
|| nbytes
!= sizeof (struct ps_prochandle
*))
5202 return (set_errno(ENODATA
));
5204 bcopy(&t
->t_pshandle
, buf
, nbytes
);
5209 pt_xd_psinfo(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5211 const psinfo_t
*psp
;
5213 if (buf
== NULL
&& nbytes
== 0)
5214 return (sizeof (psinfo_t
));
5216 if (t
->t_pshandle
== NULL
|| (psp
= Ppsinfo(t
->t_pshandle
)) == NULL
)
5217 return (set_errno(ENODATA
));
5219 nbytes
= MIN(nbytes
, sizeof (psinfo_t
));
5220 bcopy(psp
, buf
, nbytes
);
5225 pt_xd_pstatus(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5227 const pstatus_t
*psp
;
5229 if (buf
== NULL
&& nbytes
== 0)
5230 return (sizeof (pstatus_t
));
5232 if (t
->t_pshandle
== NULL
|| (psp
= Pstatus(t
->t_pshandle
)) == NULL
)
5233 return (set_errno(ENODATA
));
5235 nbytes
= MIN(nbytes
, sizeof (pstatus_t
));
5236 bcopy(psp
, buf
, nbytes
);
5241 pt_xd_utsname(mdb_tgt_t
*t
, void *buf
, size_t nbytes
)
5245 if (buf
== NULL
&& nbytes
== 0)
5246 return (sizeof (struct utsname
));
5248 if (t
->t_pshandle
== NULL
|| Puname(t
->t_pshandle
, &uts
) != 0)
5249 return (set_errno(ENODATA
));
5251 nbytes
= MIN(nbytes
, sizeof (struct utsname
));
5252 bcopy(&uts
, buf
, nbytes
);
5257 mdb_proc_tgt_create(mdb_tgt_t
*t
, int argc
, const char *argv
[])
5259 pt_data_t
*pt
= mdb_zalloc(sizeof (pt_data_t
), UM_SLEEP
);
5261 const char *aout_path
= argc
> 0 ? argv
[0] : PT_EXEC_PATH
;
5262 const char *core_path
= argc
> 1 ? argv
[1] : NULL
;
5264 const mdb_tgt_regdesc_t
*rdp
;
5265 char execname
[MAXPATHLEN
];
5273 mdb_free(pt
, sizeof (pt_data_t
));
5274 return (set_errno(EINVAL
));
5277 if (t
->t_flags
& MDB_TGT_F_RDWR
)
5278 pt
->p_oflags
= O_RDWR
;
5280 pt
->p_oflags
= O_RDONLY
;
5282 if (t
->t_flags
& MDB_TGT_F_FORCE
)
5283 pt
->p_gflags
|= PGRAB_FORCE
;
5284 if (t
->t_flags
& MDB_TGT_F_NOSTOP
)
5285 pt
->p_gflags
|= PGRAB_NOSTOP
;
5287 pt
->p_ptl_ops
= &proc_lwp_ops
;
5288 pt
->p_maxsig
= sysconf(_SC_SIGRT_MAX
);
5290 (void) mdb_nv_create(&pt
->p_regs
, UM_SLEEP
);
5291 (void) mdb_nv_create(&pt
->p_env
, UM_SLEEP
);
5293 t
->t_ops
= &proc_ops
;
5297 * If no core file name was specified, but the file ./core is present,
5298 * infer that we want to debug it. I find this behavior confusing,
5299 * so we only do this when precise adb(1) compatibility is required.
5301 if (core_path
== NULL
&& (mdb
.m_flags
& MDB_FL_ADB
) &&
5302 access(PT_CORE_PATH
, F_OK
) == 0)
5303 core_path
= PT_CORE_PATH
;
5306 * For compatibility with adb(1), the special name "-" may be used
5307 * to suppress the loading of the executable or core file.
5309 if (aout_path
!= NULL
&& strcmp(aout_path
, "-") == 0)
5311 if (core_path
!= NULL
&& strcmp(core_path
, "-") == 0)
5315 * If a core file or pid was specified, attempt to grab it now using
5316 * proc_arg_grab(); otherwise we'll create a fresh process later.
5318 if (core_path
!= NULL
&& (t
->t_pshandle
= proc_arg_xgrab(core_path
,
5319 aout_path
== PT_EXEC_PATH
? NULL
: aout_path
, PR_ARG_ANY
,
5320 pt
->p_gflags
, &perr
, NULL
)) == NULL
) {
5321 mdb_warn("cannot debug %s: %s\n", core_path
, Pgrab_error(perr
));
5325 if (aout_path
!= NULL
&&
5326 (pt
->p_idlehandle
= Pgrab_file(aout_path
, &perr
)) != NULL
&&
5327 t
->t_pshandle
== NULL
)
5328 t
->t_pshandle
= pt
->p_idlehandle
;
5330 if (t
->t_pshandle
!= NULL
)
5331 state
= Pstate(t
->t_pshandle
);
5334 * Make sure we'll have enough file descriptors to handle a target
5335 * has many many mappings.
5337 if (getrlimit(RLIMIT_NOFILE
, &rlim
) == 0) {
5338 rlim
.rlim_cur
= rlim
.rlim_max
;
5339 (void) setrlimit(RLIMIT_NOFILE
, &rlim
);
5340 (void) enable_extended_FILE_stdio(-1, -1);
5344 * If we don't have an executable path or the executable path is the
5345 * /proc/<pid>/object/a.out path, but we now have a libproc handle,
5346 * attempt to derive the executable path using Pexecname(). We need
5347 * to do this in the /proc case in order to open the executable for
5348 * writing because /proc/object/<file> permission are masked with 0555.
5349 * If Pexecname() fails us, fall back to /proc/<pid>/object/a.out.
5351 if (t
->t_pshandle
!= NULL
&& (aout_path
== NULL
|| (stat64(aout_path
,
5352 &st
) == 0 && strcmp(st
.st_fstype
, "proc") == 0))) {
5354 aout_path
= Pexecname(t
->t_pshandle
, execname
, MAXPATHLEN
);
5355 if (aout_path
== NULL
&& state
!= PS_DEAD
&& state
!= PS_IDLE
) {
5356 (void) mdb_iob_snprintf(execname
, sizeof (execname
),
5357 "/proc/%d/object/a.out",
5358 (int)Pstatus(t
->t_pshandle
)->pr_pid
);
5359 aout_path
= execname
;
5361 if (aout_path
== NULL
&&
5362 Plookup_by_name(t
->t_pshandle
, "a.out", "_start", &s
) != 0)
5363 mdb_warn("warning: failed to infer pathname to "
5364 "executable; symbol table will not be available\n");
5366 mdb_dprintf(MDB_DBG_TGT
, "a.out is %s\n", aout_path
);
5370 * Attempt to open the executable file. We only want this operation
5371 * to actually cause the constructor to abort if the executable file
5372 * name was given explicitly. If we defaulted to PT_EXEC_PATH or
5373 * derived the executable using Pexecname, then we want to continue
5374 * along with p_fio and p_file set to NULL.
5376 if (aout_path
!= NULL
&& (pt
->p_aout_fio
= mdb_fdio_create_path(NULL
,
5377 aout_path
, pt
->p_oflags
, 0)) == NULL
&& argc
> 0) {
5378 mdb_warn("failed to open %s", aout_path
);
5383 * Now create an ELF file from the input file, if we have one. Again,
5384 * only abort the constructor if the name was given explicitly.
5386 if (pt
->p_aout_fio
!= NULL
&& pt_open_aout(t
,
5387 mdb_io_hold(pt
->p_aout_fio
)) == NULL
&& argc
> 0)
5391 * If we've successfully opened an ELF file, select the appropriate
5392 * disassembler based on the ELF header.
5394 if (pt
->p_file
!= NULL
)
5395 (void) mdb_dis_select(pt_disasm(&pt
->p_file
->gf_ehdr
));
5397 (void) mdb_dis_select(pt_disasm(NULL
));
5400 * Add each register described in the target ISA register description
5401 * list to our hash table of register descriptions and then add any
5402 * appropriate ISA-specific floating-point register descriptions.
5404 for (rdp
= pt_regdesc
; rdp
->rd_name
!= NULL
; rdp
++) {
5405 (void) mdb_nv_insert(&pt
->p_regs
, rdp
->rd_name
, NULL
,
5406 MDB_TGT_R_NVAL(rdp
->rd_num
, rdp
->rd_flags
), MDB_NV_RDONLY
);
5411 * Certain important /proc structures may be of interest to mdb
5412 * modules and their dcmds. Export these using the xdata interface:
5414 (void) mdb_tgt_xdata_insert(t
, "auxv",
5415 "procfs auxv_t array", pt_xd_auxv
);
5416 (void) mdb_tgt_xdata_insert(t
, "cred",
5417 "procfs prcred_t structure", pt_xd_cred
);
5418 (void) mdb_tgt_xdata_insert(t
, "ehdr",
5419 "executable file GElf_Ehdr structure", pt_xd_ehdr
);
5420 (void) mdb_tgt_xdata_insert(t
, "lwpstatus",
5421 "procfs lwpstatus_t array", pt_xd_lwpstatus
);
5422 (void) mdb_tgt_xdata_insert(t
, "pshandle",
5423 "libproc proc service API handle", pt_xd_pshandle
);
5424 (void) mdb_tgt_xdata_insert(t
, "psinfo",
5425 "procfs psinfo_t structure", pt_xd_psinfo
);
5426 (void) mdb_tgt_xdata_insert(t
, "pstatus",
5427 "procfs pstatus_t structure", pt_xd_pstatus
);
5428 (void) mdb_tgt_xdata_insert(t
, "utsname",
5429 "utsname structure", pt_xd_utsname
);
5432 * Force a status update now so that we fill in t_status with the
5433 * latest information based on any successful grab.
5435 (void) mdb_tgt_status(t
, &t
->t_status
);
5438 * If we're not examining a core file, trace SIGINT and all signals
5439 * that cause the process to dump core as part of our initialization.
5441 if ((t
->t_pshandle
!= NULL
&& state
!= PS_DEAD
&& state
!= PS_IDLE
) ||
5442 (pt
->p_file
!= NULL
&& pt
->p_file
->gf_ehdr
.e_type
== ET_EXEC
)) {
5444 int tflag
= MDB_TGT_SPEC_STICKY
; /* default sigs are sticky */
5446 (void) mdb_tgt_add_signal(t
, SIGINT
, tflag
, no_se_f
, NULL
);
5447 (void) mdb_tgt_add_signal(t
, SIGQUIT
, tflag
, no_se_f
, NULL
);
5448 (void) mdb_tgt_add_signal(t
, SIGILL
, tflag
, no_se_f
, NULL
);
5449 (void) mdb_tgt_add_signal(t
, SIGTRAP
, tflag
, no_se_f
, NULL
);
5450 (void) mdb_tgt_add_signal(t
, SIGABRT
, tflag
, no_se_f
, NULL
);
5451 (void) mdb_tgt_add_signal(t
, SIGEMT
, tflag
, no_se_f
, NULL
);
5452 (void) mdb_tgt_add_signal(t
, SIGFPE
, tflag
, no_se_f
, NULL
);
5453 (void) mdb_tgt_add_signal(t
, SIGBUS
, tflag
, no_se_f
, NULL
);
5454 (void) mdb_tgt_add_signal(t
, SIGSEGV
, tflag
, no_se_f
, NULL
);
5455 (void) mdb_tgt_add_signal(t
, SIGSYS
, tflag
, no_se_f
, NULL
);
5456 (void) mdb_tgt_add_signal(t
, SIGXCPU
, tflag
, no_se_f
, NULL
);
5457 (void) mdb_tgt_add_signal(t
, SIGXFSZ
, tflag
, no_se_f
, NULL
);
5461 * If we've grabbed a live process, establish our initial breakpoints
5462 * and librtld_db agent so we can track rtld activity. If FL_VCREATE
5463 * is set, this process was created by a previous instantiation of
5464 * the debugger, so reset pr_flags to kill it; otherwise we attached
5465 * to an already running process. Pgrab() has already set the PR_RLC
5466 * flag appropriately based on whether the process was stopped when we
5469 if (t
->t_pshandle
!= NULL
&& state
!= PS_DEAD
&& state
!= PS_IDLE
) {
5470 if (mdb
.m_flags
& MDB_FL_VCREATE
) {
5471 (void) Punsetflags(t
->t_pshandle
, PR_RLC
);
5472 (void) Psetflags(t
->t_pshandle
, PR_KLC
);
5473 pt
->p_rflags
= PRELEASE_KILL
;
5475 (void) Punsetflags(t
->t_pshandle
, PR_KLC
);
5481 * Initialize a local copy of the environment, which can be modified
5482 * before running the program.
5484 for (i
= 0; mdb
.m_env
[i
] != NULL
; i
++)
5485 pt_env_set(pt
, mdb
.m_env
[i
]);
5488 * If adb(1) compatibility mode is on, then print the appropriate
5489 * greeting message if we have grabbed a core file.
5491 if ((mdb
.m_flags
& MDB_FL_ADB
) && t
->t_pshandle
!= NULL
&&
5493 const pstatus_t
*psp
= Pstatus(t
->t_pshandle
);
5494 int cursig
= psp
->pr_lwp
.pr_cursig
;
5495 char signame
[SIG2STR_MAX
];
5497 mdb_printf("core file = %s -- program ``%s'' on platform %s\n",
5498 core_path
, aout_path
? aout_path
: "?", pt_platform(t
));
5500 if (cursig
!= 0 && sig2str(cursig
, signame
) == 0)
5501 mdb_printf("SIG%s: %s\n", signame
, strsignal(cursig
));