17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*9acbbeafSnn * Common Development and Distribution License (the "License"). 6*9acbbeafSnn * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*9acbbeafSnn * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/mman.h> 307c478bd9Sstevel@tonic-gate #include <sys/priocntl.h> 317c478bd9Sstevel@tonic-gate #include <sys/rtpriocntl.h> 327c478bd9Sstevel@tonic-gate #include <sys/resource.h> 337c478bd9Sstevel@tonic-gate #include <sys/termios.h> 347c478bd9Sstevel@tonic-gate #include <sys/param.h> 357c478bd9Sstevel@tonic-gate #include <sys/regset.h> 367c478bd9Sstevel@tonic-gate #include <sys/frame.h> 377c478bd9Sstevel@tonic-gate #include <sys/stack.h> 387c478bd9Sstevel@tonic-gate #include <sys/reg.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include <libproc.h> 417c478bd9Sstevel@tonic-gate #include <libscf.h> 427c478bd9Sstevel@tonic-gate #include <alloca.h> 437c478bd9Sstevel@tonic-gate #include <unistd.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <stdlib.h> 467c478bd9Sstevel@tonic-gate #include <fcntl.h> 477c478bd9Sstevel@tonic-gate #include <dlfcn.h> 487c478bd9Sstevel@tonic-gate #include <libctf.h> 497c478bd9Sstevel@tonic-gate #include <errno.h> 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #include <mdb/mdb_lex.h> 527c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h> 537c478bd9Sstevel@tonic-gate #include <mdb/mdb_signal.h> 547c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h> 557c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 567c478bd9Sstevel@tonic-gate #include <mdb/mdb_target.h> 577c478bd9Sstevel@tonic-gate #include <mdb/mdb_gelf.h> 587c478bd9Sstevel@tonic-gate #include <mdb/mdb_conf.h> 597c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h> 607c478bd9Sstevel@tonic-gate #include <mdb/mdb_io_impl.h> 617c478bd9Sstevel@tonic-gate #include <mdb/mdb_frame.h> 627c478bd9Sstevel@tonic-gate #include <mdb/mdb_set.h> 637c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_kctl.h> 647c478bd9Sstevel@tonic-gate #include <mdb/mdb.h> 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #ifndef STACK_BIAS 677c478bd9Sstevel@tonic-gate #define STACK_BIAS 0 687c478bd9Sstevel@tonic-gate #endif 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #if defined(__sparc) 717c478bd9Sstevel@tonic-gate #define STACK_REGISTER SP 727c478bd9Sstevel@tonic-gate #else 737c478bd9Sstevel@tonic-gate #define STACK_REGISTER REG_FP 747c478bd9Sstevel@tonic-gate #endif 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #ifdef _LP64 777c478bd9Sstevel@tonic-gate #define MDB_DEF_IPATH \ 787c478bd9Sstevel@tonic-gate "%r/usr/platform/%p/lib/adb/%i:" \ 797c478bd9Sstevel@tonic-gate "%r/usr/platform/%m/lib/adb/%i:" \ 807c478bd9Sstevel@tonic-gate "%r/usr/lib/adb/%i" 817c478bd9Sstevel@tonic-gate #define MDB_DEF_LPATH \ 827c478bd9Sstevel@tonic-gate "%r/usr/platform/%p/lib/mdb/%t/%i:" \ 837c478bd9Sstevel@tonic-gate "%r/usr/platform/%m/lib/mdb/%t/%i:" \ 847c478bd9Sstevel@tonic-gate "%r/usr/lib/mdb/%t/%i" 857c478bd9Sstevel@tonic-gate #else 867c478bd9Sstevel@tonic-gate #define MDB_DEF_IPATH \ 877c478bd9Sstevel@tonic-gate "%r/usr/platform/%p/lib/adb:" \ 887c478bd9Sstevel@tonic-gate "%r/usr/platform/%m/lib/adb:" \ 897c478bd9Sstevel@tonic-gate "%r/usr/lib/adb" 907c478bd9Sstevel@tonic-gate #define MDB_DEF_LPATH \ 917c478bd9Sstevel@tonic-gate "%r/usr/platform/%p/lib/mdb/%t:" \ 927c478bd9Sstevel@tonic-gate "%r/usr/platform/%m/lib/mdb/%t:" \ 937c478bd9Sstevel@tonic-gate "%r/usr/lib/mdb/%t" 947c478bd9Sstevel@tonic-gate #endif 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate #define MDB_DEF_PROMPT "> " 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Similar to the panic_* variables in the kernel, we keep some relevant 1007c478bd9Sstevel@tonic-gate * information stored in a set of global _mdb_abort_* variables; in the 1017c478bd9Sstevel@tonic-gate * event that the debugger dumps core, these will aid core dump analysis. 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate const char *volatile _mdb_abort_str; /* reason for failure */ 1047c478bd9Sstevel@tonic-gate siginfo_t _mdb_abort_info; /* signal info for fatal signal */ 1057c478bd9Sstevel@tonic-gate ucontext_t _mdb_abort_ctx; /* context fatal signal interrupted */ 1067c478bd9Sstevel@tonic-gate int _mdb_abort_rcount; /* number of times resume requested */ 1077c478bd9Sstevel@tonic-gate int _mdb_self_fd = -1; /* fd for self as for valid_frame */ 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate static void 1107c478bd9Sstevel@tonic-gate terminate(int status) 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate mdb_destroy(); 1137c478bd9Sstevel@tonic-gate exit(status); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate static void 1177c478bd9Sstevel@tonic-gate print_frame(uintptr_t pc, int fnum) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate Dl_info dli; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate if (dladdr((void *)pc, &dli)) { 1227c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, " [%d] %s`%s+0x%lx()\n", fnum, 1237c478bd9Sstevel@tonic-gate strbasename(dli.dli_fname), dli.dli_sname, 1247c478bd9Sstevel@tonic-gate pc - (uintptr_t)dli.dli_saddr); 1257c478bd9Sstevel@tonic-gate } else 1267c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, " [%d] %p()\n", fnum, pc); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate static int 1307c478bd9Sstevel@tonic-gate valid_frame(struct frame *fr) 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate static struct frame fake; 1337c478bd9Sstevel@tonic-gate uintptr_t addr = (uintptr_t)fr; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (pread(_mdb_self_fd, &fake, sizeof (fake), addr) != sizeof (fake)) { 1367c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, " invalid frame (%p)\n", fr); 1377c478bd9Sstevel@tonic-gate return (0); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate if (addr & (STACK_ALIGN - 1)) { 1417c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, " mis-aligned frame (%p)\n", fr); 1427c478bd9Sstevel@tonic-gate return (0); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate return (1); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1497c478bd9Sstevel@tonic-gate static void 1507c478bd9Sstevel@tonic-gate flt_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate static const struct rlimit rl = { 1537c478bd9Sstevel@tonic-gate (rlim_t)RLIM_INFINITY, (rlim_t)RLIM_INFINITY 1547c478bd9Sstevel@tonic-gate }; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate const mdb_idcmd_t *idcp = NULL; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (mdb.m_frame != NULL && mdb.m_frame->f_cp != NULL) 1597c478bd9Sstevel@tonic-gate idcp = mdb.m_frame->f_cp->c_dcmd; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if (sip != NULL) 1627c478bd9Sstevel@tonic-gate bcopy(sip, &_mdb_abort_info, sizeof (_mdb_abort_info)); 1637c478bd9Sstevel@tonic-gate if (ucp != NULL) 1647c478bd9Sstevel@tonic-gate bcopy(ucp, &_mdb_abort_ctx, sizeof (_mdb_abort_ctx)); 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate _mdb_abort_info.si_signo = sig; 1677c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(sig, SIG_DFL, NULL); 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * If there is no current dcmd, or the current dcmd comes from a 1717c478bd9Sstevel@tonic-gate * builtin module, we don't allow resume and always core dump. 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate if (idcp == NULL || idcp->idc_modp == NULL || 1747c478bd9Sstevel@tonic-gate idcp->idc_modp == &mdb.m_rmod || idcp->idc_modp->mod_hdl == NULL) 1757c478bd9Sstevel@tonic-gate goto dump; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (mdb.m_term != NULL) { 1787c478bd9Sstevel@tonic-gate struct frame *fr = (struct frame *) 1797c478bd9Sstevel@tonic-gate (ucp->uc_mcontext.gregs[STACK_REGISTER] + STACK_BIAS); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate char signame[SIG2STR_MAX]; 1827c478bd9Sstevel@tonic-gate int i = 1; 1837c478bd9Sstevel@tonic-gate char c; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (sig2str(sig, signame) == -1) { 1867c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, 1877c478bd9Sstevel@tonic-gate "\n*** %s: received signal %d at:\n", 1887c478bd9Sstevel@tonic-gate mdb.m_pname, sig); 1897c478bd9Sstevel@tonic-gate } else { 1907c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, 1917c478bd9Sstevel@tonic-gate "\n*** %s: received signal %s at:\n", 1927c478bd9Sstevel@tonic-gate mdb.m_pname, signame); 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (ucp->uc_mcontext.gregs[REG_PC] != 0) 1967c478bd9Sstevel@tonic-gate print_frame(ucp->uc_mcontext.gregs[REG_PC], i++); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate while (fr != NULL && valid_frame(fr) && fr->fr_savpc != 0) { 1997c478bd9Sstevel@tonic-gate print_frame(fr->fr_savpc, i++); 2007c478bd9Sstevel@tonic-gate fr = (struct frame *) 2017c478bd9Sstevel@tonic-gate ((uintptr_t)fr->fr_savfp + STACK_BIAS); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate query: 2057c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, "\n%s: (c)ore dump, (q)uit, " 2067c478bd9Sstevel@tonic-gate "(r)ecover, or (s)top for debugger [cqrs]? ", mdb.m_pname); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate mdb_iob_flush(mdb.m_err); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate for (;;) { 2117c478bd9Sstevel@tonic-gate if (IOP_READ(mdb.m_term, &c, sizeof (c)) != sizeof (c)) 2127c478bd9Sstevel@tonic-gate goto dump; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate switch (c) { 2157c478bd9Sstevel@tonic-gate case 'c': 2167c478bd9Sstevel@tonic-gate case 'C': 2177c478bd9Sstevel@tonic-gate (void) setrlimit(RLIMIT_CORE, &rl); 2187c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, "\n%s: attempting " 2197c478bd9Sstevel@tonic-gate "to dump core ...\n", mdb.m_pname); 2207c478bd9Sstevel@tonic-gate goto dump; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate case 'q': 2237c478bd9Sstevel@tonic-gate case 'Q': 2247c478bd9Sstevel@tonic-gate mdb_iob_discard(mdb.m_out); 2257c478bd9Sstevel@tonic-gate mdb_iob_nl(mdb.m_err); 2267c478bd9Sstevel@tonic-gate (void) mdb_signal_unblockall(); 2277c478bd9Sstevel@tonic-gate terminate(1); 2287c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate case 'r': 2317c478bd9Sstevel@tonic-gate case 'R': 2327c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, "\n%s: unloading " 2337c478bd9Sstevel@tonic-gate "module '%s' ...\n", mdb.m_pname, 2347c478bd9Sstevel@tonic-gate idcp->idc_modp->mod_name); 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate (void) mdb_module_unload( 2377c478bd9Sstevel@tonic-gate idcp->idc_modp->mod_name, 0); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(sig, 2407c478bd9Sstevel@tonic-gate flt_handler, NULL); 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate _mdb_abort_rcount++; 2437c478bd9Sstevel@tonic-gate mdb.m_intr = 0; 2447c478bd9Sstevel@tonic-gate mdb.m_pend = 0; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate (void) mdb_signal_unblockall(); 2477c478bd9Sstevel@tonic-gate longjmp(mdb.m_frame->f_pcb, MDB_ERR_ABORT); 2487c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate case 's': 2517c478bd9Sstevel@tonic-gate case 'S': 2527c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, "\n%s: " 2537c478bd9Sstevel@tonic-gate "attempting to stop pid %d ...\n", 2547c478bd9Sstevel@tonic-gate mdb.m_pname, (int)getpid()); 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* 2577c478bd9Sstevel@tonic-gate * Stop ourself; if this fails or we are 2587c478bd9Sstevel@tonic-gate * subsequently continued, ask again. 2597c478bd9Sstevel@tonic-gate */ 2607c478bd9Sstevel@tonic-gate (void) mdb_signal_raise(SIGSTOP); 2617c478bd9Sstevel@tonic-gate (void) mdb_signal_unblockall(); 2627c478bd9Sstevel@tonic-gate goto query; 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate dump: 2687c478bd9Sstevel@tonic-gate if (SI_FROMUSER(sip)) { 2697c478bd9Sstevel@tonic-gate (void) mdb_signal_block(sig); 2707c478bd9Sstevel@tonic-gate (void) mdb_signal_raise(sig); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate (void) sigfillset(&ucp->uc_sigmask); 2747c478bd9Sstevel@tonic-gate (void) sigdelset(&ucp->uc_sigmask, sig); 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate if (_mdb_abort_str == NULL) 2777c478bd9Sstevel@tonic-gate _mdb_abort_str = "fatal signal received"; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate ucp->uc_flags |= UC_SIGMASK; 2807c478bd9Sstevel@tonic-gate (void) setcontext(ucp); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2847c478bd9Sstevel@tonic-gate static void 2857c478bd9Sstevel@tonic-gate int_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate if (mdb.m_intr == 0) 2887c478bd9Sstevel@tonic-gate longjmp(mdb.m_frame->f_pcb, MDB_ERR_SIGINT); 2897c478bd9Sstevel@tonic-gate else 2907c478bd9Sstevel@tonic-gate mdb.m_pend++; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate static void 2947c478bd9Sstevel@tonic-gate control_kmdb(int start) 2957c478bd9Sstevel@tonic-gate { 2967c478bd9Sstevel@tonic-gate int fd; 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate if ((fd = open("/dev/kmdb", O_RDONLY)) < 0) 2997c478bd9Sstevel@tonic-gate die("failed to open /dev/kmdb"); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (start) { 3027c478bd9Sstevel@tonic-gate char *state = mdb_get_config(); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate if (ioctl(fd, KMDB_IOC_START, state) < 0) 3057c478bd9Sstevel@tonic-gate die("failed to start kmdb"); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate strfree(state); 3087c478bd9Sstevel@tonic-gate } else { 3097c478bd9Sstevel@tonic-gate if (ioctl(fd, KMDB_IOC_STOP) < 0) 3107c478bd9Sstevel@tonic-gate die("failed to stop kmdb"); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate close(fd); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate static void 3177c478bd9Sstevel@tonic-gate usage(int status) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_err, "Usage: %s [-fkmuwyAFKMSUW] [+/-o option] " 3207c478bd9Sstevel@tonic-gate "[-p pid] [-s dist] [-I path] [-L path]\n\t[-P prompt] " 3217c478bd9Sstevel@tonic-gate "[-R root] [-V dis-version] [object [core] | core | suffix]\n\n", 3227c478bd9Sstevel@tonic-gate mdb.m_pname); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_err, 3257c478bd9Sstevel@tonic-gate "\t-f force raw file debugging mode\n" 3267c478bd9Sstevel@tonic-gate "\t-k force kernel debugging mode\n" 3277c478bd9Sstevel@tonic-gate "\t-m disable demand-loading of module symbols\n" 3287c478bd9Sstevel@tonic-gate "\t-o set specified debugger option (+o to unset)\n" 3297c478bd9Sstevel@tonic-gate "\t-p attach to specified process-id\n" 3307c478bd9Sstevel@tonic-gate "\t-s set symbol matching distance\n" 3317c478bd9Sstevel@tonic-gate "\t-u force user program debugging mode\n" 3327c478bd9Sstevel@tonic-gate "\t-w enable write mode\n" 3337c478bd9Sstevel@tonic-gate "\t-y send terminal initialization sequences for tty mode\n" 3347c478bd9Sstevel@tonic-gate "\t-A disable automatic loading of mdb modules\n" 3357c478bd9Sstevel@tonic-gate "\t-F enable forcible takeover mode\n" 3367c478bd9Sstevel@tonic-gate "\t-K stop operating system and enter live kernel debugger\n" 3377c478bd9Sstevel@tonic-gate "\t-M preload all module symbols\n" 3387c478bd9Sstevel@tonic-gate "\t-I set initial path for macro files\n" 3397c478bd9Sstevel@tonic-gate "\t-L set initial path for module libs\n" 3407c478bd9Sstevel@tonic-gate "\t-P set command-line prompt\n" 3417c478bd9Sstevel@tonic-gate "\t-R set root directory for pathname expansion\n" 3427c478bd9Sstevel@tonic-gate "\t-S suppress processing of ~/.mdbrc file\n" 3437c478bd9Sstevel@tonic-gate "\t-U unload live kernel debugger\n" 3447c478bd9Sstevel@tonic-gate "\t-W enable I/O-mapped memory access (kernel only)\n" 3457c478bd9Sstevel@tonic-gate "\t-V set disassembler version\n"); 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate terminate(status); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate static char * 3517c478bd9Sstevel@tonic-gate mdb_scf_console_term(void) 3527c478bd9Sstevel@tonic-gate { 3537c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 3547c478bd9Sstevel@tonic-gate char *term = NULL; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, 3577c478bd9Sstevel@tonic-gate "svc:/system/console-login:default", "ttymon", 3587c478bd9Sstevel@tonic-gate "terminal_type")) == NULL) 3597c478bd9Sstevel@tonic-gate return (NULL); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if (scf_simple_prop_type(prop) == SCF_TYPE_ASTRING && 3627c478bd9Sstevel@tonic-gate (term = scf_simple_prop_next_astring(prop)) != NULL) 3637c478bd9Sstevel@tonic-gate term = strdup(term); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 3667c478bd9Sstevel@tonic-gate return (term); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate int 3707c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 3717c478bd9Sstevel@tonic-gate { 3727c478bd9Sstevel@tonic-gate mdb_tgt_ctor_f *tgt_ctor = NULL; 3737c478bd9Sstevel@tonic-gate const char **tgt_argv = alloca(argc * sizeof (char *)); 3747c478bd9Sstevel@tonic-gate int tgt_argc = 0; 3757c478bd9Sstevel@tonic-gate mdb_tgt_t *tgt; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate char object[MAXPATHLEN], execname[MAXPATHLEN]; 3787c478bd9Sstevel@tonic-gate mdb_io_t *in_io, *out_io, *err_io, *null_io; 3797c478bd9Sstevel@tonic-gate struct termios tios; 3807c478bd9Sstevel@tonic-gate int status, c; 3817c478bd9Sstevel@tonic-gate char *p; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate const char *Iflag = NULL, *Lflag = NULL, *Vflag = NULL, *pidarg = NULL; 3847c478bd9Sstevel@tonic-gate int Kflag = 0, Rflag = 0, Sflag = 0, Oflag = 0, Uflag = 0; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate int ttylike; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate stack_t sigstack; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if (realpath(getexecname(), execname) == NULL) { 3917c478bd9Sstevel@tonic-gate (void) strncpy(execname, argv[0], MAXPATHLEN); 3927c478bd9Sstevel@tonic-gate execname[MAXPATHLEN - 1] = '\0'; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate mdb_create(execname, argv[0]); 3967c478bd9Sstevel@tonic-gate bzero(tgt_argv, argc * sizeof (char *)); 3977c478bd9Sstevel@tonic-gate argv[0] = (char *)mdb.m_pname; 3987c478bd9Sstevel@tonic-gate _mdb_self_fd = open("/proc/self/as", O_RDONLY); 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate mdb.m_env = envp; 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate out_io = mdb_fdio_create(STDOUT_FILENO); 4037c478bd9Sstevel@tonic-gate mdb.m_out = mdb_iob_create(out_io, MDB_IOB_WRONLY); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate err_io = mdb_fdio_create(STDERR_FILENO); 4067c478bd9Sstevel@tonic-gate mdb.m_err = mdb_iob_create(err_io, MDB_IOB_WRONLY); 4077c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_err, MDB_IOB_AUTOWRAP); 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate null_io = mdb_nullio_create(); 4107c478bd9Sstevel@tonic-gate mdb.m_null = mdb_iob_create(null_io, MDB_IOB_WRONLY); 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate in_io = mdb_fdio_create(STDIN_FILENO); 4137c478bd9Sstevel@tonic-gate if ((mdb.m_termtype = getenv("TERM")) != NULL) { 4147c478bd9Sstevel@tonic-gate mdb.m_termtype = strdup(mdb.m_termtype); 4157c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_TERMGUESS; 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate mdb.m_term = NULL; 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate mdb_dmode(mdb_dstr2mode(getenv("MDB_DEBUG"))); 4207c478bd9Sstevel@tonic-gate mdb.m_pgid = getpgrp(); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate if (getenv("_MDB_EXEC") != NULL) 4237c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_EXEC; 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate /* 4267c478bd9Sstevel@tonic-gate * Setup an alternate signal stack. When tearing down pipelines in 4277c478bd9Sstevel@tonic-gate * terminate(), we may have to destroy the stack of the context in 4287c478bd9Sstevel@tonic-gate * which we are currently executing the signal handler. 4297c478bd9Sstevel@tonic-gate */ 4307c478bd9Sstevel@tonic-gate sigstack.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, 4317c478bd9Sstevel@tonic-gate MAP_PRIVATE | MAP_ANON, -1, 0); 4327c478bd9Sstevel@tonic-gate if (sigstack.ss_sp == MAP_FAILED) 4337c478bd9Sstevel@tonic-gate die("could not allocate signal stack"); 4347c478bd9Sstevel@tonic-gate sigstack.ss_size = SIGSTKSZ; 4357c478bd9Sstevel@tonic-gate sigstack.ss_flags = 0; 4367c478bd9Sstevel@tonic-gate if (sigaltstack(&sigstack, NULL) != 0) 4377c478bd9Sstevel@tonic-gate die("could not set signal stack"); 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGPIPE, SIG_IGN, NULL); 4407c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGQUIT, SIG_IGN, NULL); 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGILL, flt_handler, NULL); 4437c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGTRAP, flt_handler, NULL); 4447c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGIOT, flt_handler, NULL); 4457c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGEMT, flt_handler, NULL); 4467c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGFPE, flt_handler, NULL); 4477c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGBUS, flt_handler, NULL); 4487c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGSEGV, flt_handler, NULL); 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGHUP, (mdb_signal_f *)terminate, NULL); 4517c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGTERM, (mdb_signal_f *)terminate, NULL); 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate for (mdb.m_rdvers = RD_VERSION; mdb.m_rdvers > 0; mdb.m_rdvers--) { 4547c478bd9Sstevel@tonic-gate if (rd_init(mdb.m_rdvers) == RD_OK) 4557c478bd9Sstevel@tonic-gate break; 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate for (mdb.m_ctfvers = CTF_VERSION; mdb.m_ctfvers > 0; mdb.m_ctfvers--) { 4597c478bd9Sstevel@tonic-gate if (ctf_version(mdb.m_ctfvers) != -1) 4607c478bd9Sstevel@tonic-gate break; 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if ((p = getenv("HISTSIZE")) != NULL && strisnum(p)) { 4647c478bd9Sstevel@tonic-gate mdb.m_histlen = strtoi(p); 4657c478bd9Sstevel@tonic-gate if (mdb.m_histlen < 1) 4667c478bd9Sstevel@tonic-gate mdb.m_histlen = 1; 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate while (optind < argc) { 4707c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, 4717c478bd9Sstevel@tonic-gate "fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) { 4727c478bd9Sstevel@tonic-gate switch (c) { 4737c478bd9Sstevel@tonic-gate case 'f': 4747c478bd9Sstevel@tonic-gate tgt_ctor = mdb_rawfile_tgt_create; 4757c478bd9Sstevel@tonic-gate break; 4767c478bd9Sstevel@tonic-gate case 'k': 4777c478bd9Sstevel@tonic-gate tgt_ctor = mdb_kvm_tgt_create; 4787c478bd9Sstevel@tonic-gate break; 4797c478bd9Sstevel@tonic-gate case 'm': 4807c478bd9Sstevel@tonic-gate mdb.m_tgtflags |= MDB_TGT_F_NOLOAD; 4817c478bd9Sstevel@tonic-gate mdb.m_tgtflags &= ~MDB_TGT_F_PRELOAD; 4827c478bd9Sstevel@tonic-gate break; 4837c478bd9Sstevel@tonic-gate case 'o': 4847c478bd9Sstevel@tonic-gate if (!mdb_set_options(optarg, TRUE)) 4857c478bd9Sstevel@tonic-gate terminate(2); 4867c478bd9Sstevel@tonic-gate break; 4877c478bd9Sstevel@tonic-gate case 'p': 4887c478bd9Sstevel@tonic-gate tgt_ctor = mdb_proc_tgt_create; 4897c478bd9Sstevel@tonic-gate pidarg = optarg; 4907c478bd9Sstevel@tonic-gate break; 4917c478bd9Sstevel@tonic-gate case 's': 4927c478bd9Sstevel@tonic-gate if (!strisnum(optarg)) { 4937c478bd9Sstevel@tonic-gate warn("expected integer following -s\n"); 4947c478bd9Sstevel@tonic-gate terminate(2); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate mdb.m_symdist = (size_t)(uint_t)strtoi(optarg); 4977c478bd9Sstevel@tonic-gate break; 4987c478bd9Sstevel@tonic-gate case 'u': 4997c478bd9Sstevel@tonic-gate tgt_ctor = mdb_proc_tgt_create; 5007c478bd9Sstevel@tonic-gate break; 5017c478bd9Sstevel@tonic-gate case 'w': 5027c478bd9Sstevel@tonic-gate mdb.m_tgtflags |= MDB_TGT_F_RDWR; 5037c478bd9Sstevel@tonic-gate break; 5047c478bd9Sstevel@tonic-gate case 'y': 5057c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_USECUP; 5067c478bd9Sstevel@tonic-gate break; 5077c478bd9Sstevel@tonic-gate case 'A': 5087c478bd9Sstevel@tonic-gate (void) mdb_set_options("nomods", TRUE); 5097c478bd9Sstevel@tonic-gate break; 5107c478bd9Sstevel@tonic-gate case 'C': 5117c478bd9Sstevel@tonic-gate (void) mdb_set_options("noctf", TRUE); 5127c478bd9Sstevel@tonic-gate break; 5137c478bd9Sstevel@tonic-gate case 'D': 5147c478bd9Sstevel@tonic-gate mdb_dmode(mdb_dstr2mode(optarg)); 5157c478bd9Sstevel@tonic-gate break; 5167c478bd9Sstevel@tonic-gate case 'F': 5177c478bd9Sstevel@tonic-gate mdb.m_tgtflags |= MDB_TGT_F_FORCE; 5187c478bd9Sstevel@tonic-gate break; 5197c478bd9Sstevel@tonic-gate case 'I': 5207c478bd9Sstevel@tonic-gate Iflag = optarg; 5217c478bd9Sstevel@tonic-gate break; 5227c478bd9Sstevel@tonic-gate case 'L': 5237c478bd9Sstevel@tonic-gate Lflag = optarg; 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate case 'K': 5267c478bd9Sstevel@tonic-gate Kflag++; 5277c478bd9Sstevel@tonic-gate break; 5287c478bd9Sstevel@tonic-gate case 'M': 5297c478bd9Sstevel@tonic-gate mdb.m_tgtflags |= MDB_TGT_F_PRELOAD; 5307c478bd9Sstevel@tonic-gate mdb.m_tgtflags &= ~MDB_TGT_F_NOLOAD; 5317c478bd9Sstevel@tonic-gate break; 5327c478bd9Sstevel@tonic-gate case 'O': 5337c478bd9Sstevel@tonic-gate Oflag++; 5347c478bd9Sstevel@tonic-gate break; 5357c478bd9Sstevel@tonic-gate case 'P': 5367c478bd9Sstevel@tonic-gate if (!mdb_set_prompt(optarg)) 5377c478bd9Sstevel@tonic-gate terminate(2); 5387c478bd9Sstevel@tonic-gate break; 5397c478bd9Sstevel@tonic-gate case 'R': 5407c478bd9Sstevel@tonic-gate (void) strncpy(mdb.m_root, optarg, MAXPATHLEN); 5417c478bd9Sstevel@tonic-gate mdb.m_root[MAXPATHLEN - 1] = '\0'; 5427c478bd9Sstevel@tonic-gate Rflag++; 5437c478bd9Sstevel@tonic-gate break; 5447c478bd9Sstevel@tonic-gate case 'S': 5457c478bd9Sstevel@tonic-gate Sflag++; 5467c478bd9Sstevel@tonic-gate break; 5477c478bd9Sstevel@tonic-gate case 'U': 5487c478bd9Sstevel@tonic-gate Uflag++; 5497c478bd9Sstevel@tonic-gate break; 5507c478bd9Sstevel@tonic-gate case 'V': 5517c478bd9Sstevel@tonic-gate Vflag = optarg; 5527c478bd9Sstevel@tonic-gate break; 5537c478bd9Sstevel@tonic-gate case 'W': 5547c478bd9Sstevel@tonic-gate mdb.m_tgtflags |= MDB_TGT_F_ALLOWIO; 5557c478bd9Sstevel@tonic-gate break; 5567c478bd9Sstevel@tonic-gate case '?': 5577c478bd9Sstevel@tonic-gate if (optopt == '?') 5587c478bd9Sstevel@tonic-gate usage(0); 5597c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 5607c478bd9Sstevel@tonic-gate default: 5617c478bd9Sstevel@tonic-gate usage(2); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate if (optind < argc) { 5667c478bd9Sstevel@tonic-gate const char *arg = argv[optind++]; 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate if (arg[0] == '+' && strlen(arg) == 2) { 5697c478bd9Sstevel@tonic-gate if (arg[1] != 'o') { 5707c478bd9Sstevel@tonic-gate warn("illegal option -- %s\n", arg); 5717c478bd9Sstevel@tonic-gate terminate(2); 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate if (optind >= argc) { 5747c478bd9Sstevel@tonic-gate warn("option requires an argument -- " 5757c478bd9Sstevel@tonic-gate "%s\n", arg); 5767c478bd9Sstevel@tonic-gate terminate(2); 5777c478bd9Sstevel@tonic-gate } 5787c478bd9Sstevel@tonic-gate if (!mdb_set_options(argv[optind++], FALSE)) 5797c478bd9Sstevel@tonic-gate terminate(2); 5807c478bd9Sstevel@tonic-gate } else 5817c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = arg; 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 585*9acbbeafSnn if (rd_ctl(RD_CTL_SET_HELPPATH, (void *)mdb.m_root) != RD_OK) { 586*9acbbeafSnn warn("cannot set librtld_db helper path to %s\n", mdb.m_root); 587*9acbbeafSnn terminate(2); 588*9acbbeafSnn } 589*9acbbeafSnn 5907c478bd9Sstevel@tonic-gate if (mdb.m_debug & MDB_DBG_HELP) 5917c478bd9Sstevel@tonic-gate terminate(0); /* Quit here if we've printed out the tokens */ 5927c478bd9Sstevel@tonic-gate 593*9acbbeafSnn 5947c478bd9Sstevel@tonic-gate if (Iflag != NULL && strchr(Iflag, ';') != NULL) { 5957c478bd9Sstevel@tonic-gate warn("macro path cannot contain semicolons\n"); 5967c478bd9Sstevel@tonic-gate terminate(2); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate if (Lflag != NULL && strchr(Lflag, ';') != NULL) { 6007c478bd9Sstevel@tonic-gate warn("module path cannot contain semicolons\n"); 6017c478bd9Sstevel@tonic-gate terminate(2); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate if (Kflag || Uflag) { 6057c478bd9Sstevel@tonic-gate char *nm; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate if (tgt_ctor != NULL || Iflag != NULL) { 6087c478bd9Sstevel@tonic-gate warn("neither -f, -k, -p, -u, nor -I " 6097c478bd9Sstevel@tonic-gate "may be used with -K\n"); 6107c478bd9Sstevel@tonic-gate usage(2); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate if (Lflag != NULL) 6147c478bd9Sstevel@tonic-gate mdb_set_lpath(Lflag); 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate if ((nm = ttyname(STDIN_FILENO)) == NULL || 6177c478bd9Sstevel@tonic-gate strcmp(nm, "/dev/console") != 0) { 6187c478bd9Sstevel@tonic-gate /* 6197c478bd9Sstevel@tonic-gate * Due to the consequences of typing mdb -K instead of 6207c478bd9Sstevel@tonic-gate * mdb -k on a tty other than /dev/console, we require 6217c478bd9Sstevel@tonic-gate * -F when starting kmdb from a tty other than 6227c478bd9Sstevel@tonic-gate * /dev/console. 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate if (!(mdb.m_tgtflags & MDB_TGT_F_FORCE)) { 6257c478bd9Sstevel@tonic-gate die("-F must also be supplied to start kmdb " 6267c478bd9Sstevel@tonic-gate "from non-console tty\n"); 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate if (mdb.m_termtype == NULL || (mdb.m_flags & 6307c478bd9Sstevel@tonic-gate MDB_FL_TERMGUESS)) { 6317c478bd9Sstevel@tonic-gate if (mdb.m_termtype != NULL) 6327c478bd9Sstevel@tonic-gate strfree(mdb.m_termtype); 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate if ((mdb.m_termtype = mdb_scf_console_term()) != 6357c478bd9Sstevel@tonic-gate NULL) 6367c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_TERMGUESS; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate } else { 6397c478bd9Sstevel@tonic-gate /* 6407c478bd9Sstevel@tonic-gate * When on console, $TERM (if set) takes precedence over 6417c478bd9Sstevel@tonic-gate * the SMF setting. 6427c478bd9Sstevel@tonic-gate */ 6437c478bd9Sstevel@tonic-gate if (mdb.m_termtype == NULL && (mdb.m_termtype = 6447c478bd9Sstevel@tonic-gate mdb_scf_console_term()) != NULL) 6457c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_TERMGUESS; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate control_kmdb(Kflag); 6497c478bd9Sstevel@tonic-gate terminate(0); 6507c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate /* 6547c478bd9Sstevel@tonic-gate * If standard input appears to have tty attributes, attempt to 6557c478bd9Sstevel@tonic-gate * initialize a terminal i/o backend on top of stdin and stdout. 6567c478bd9Sstevel@tonic-gate */ 6577c478bd9Sstevel@tonic-gate ttylike = (IOP_CTL(in_io, TCGETS, &tios) == 0); 6587c478bd9Sstevel@tonic-gate if (ttylike) { 6597c478bd9Sstevel@tonic-gate if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, 6607c478bd9Sstevel@tonic-gate in_io, out_io)) == NULL) { 6617c478bd9Sstevel@tonic-gate if (!(mdb.m_flags & MDB_FL_EXEC)) { 6627c478bd9Sstevel@tonic-gate warn("term init failed: command-line editing " 6637c478bd9Sstevel@tonic-gate "and prompt will not be available\n"); 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate } else { 6667c478bd9Sstevel@tonic-gate in_io = mdb.m_term; 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY); 6717c478bd9Sstevel@tonic-gate if (mdb.m_term != NULL) { 6727c478bd9Sstevel@tonic-gate mdb_iob_setpager(mdb.m_out, mdb.m_term); 6737c478bd9Sstevel@tonic-gate if (mdb.m_flags & MDB_FL_PAGER) 6747c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE); 6757c478bd9Sstevel@tonic-gate else 6767c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE); 6777c478bd9Sstevel@tonic-gate } else if (ttylike) 6787c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE); 6797c478bd9Sstevel@tonic-gate else 6807c478bd9Sstevel@tonic-gate mdb_iob_setbuf(mdb.m_in, mdb_alloc(1, UM_SLEEP), 1); 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate mdb_pservice_init(); 6837c478bd9Sstevel@tonic-gate mdb_lex_reset(); 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate if ((mdb.m_shell = getenv("SHELL")) == NULL) 6867c478bd9Sstevel@tonic-gate mdb.m_shell = "/bin/sh"; 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate if (tgt_ctor == mdb_kvm_tgt_create) { 6897c478bd9Sstevel@tonic-gate if (pidarg != NULL) { 6907c478bd9Sstevel@tonic-gate warn("-p and -k options are mutually exclusive\n"); 6917c478bd9Sstevel@tonic-gate terminate(2); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate if (tgt_argc == 0) 6957c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = "/dev/ksyms"; 6967c478bd9Sstevel@tonic-gate if (tgt_argc == 1 && strisnum(tgt_argv[0]) == 0) { 6977c478bd9Sstevel@tonic-gate if (mdb.m_tgtflags & MDB_TGT_F_ALLOWIO) 6987c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = "/dev/allkmem"; 6997c478bd9Sstevel@tonic-gate else 7007c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = "/dev/kmem"; 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate if (pidarg != NULL) { 7057c478bd9Sstevel@tonic-gate if (tgt_argc != 0) { 7067c478bd9Sstevel@tonic-gate warn("-p may not be used with other arguments\n"); 7077c478bd9Sstevel@tonic-gate terminate(2); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate if (proc_arg_psinfo(pidarg, PR_ARG_PIDS, NULL, &status) == -1) { 7107c478bd9Sstevel@tonic-gate die("cannot attach to %s: %s\n", 7117c478bd9Sstevel@tonic-gate pidarg, Pgrab_error(status)); 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate if (strchr(pidarg, '/') != NULL) 7147c478bd9Sstevel@tonic-gate (void) mdb_iob_snprintf(object, MAXPATHLEN, 7157c478bd9Sstevel@tonic-gate "%s/object/a.out", pidarg); 7167c478bd9Sstevel@tonic-gate else 7177c478bd9Sstevel@tonic-gate (void) mdb_iob_snprintf(object, MAXPATHLEN, 7187c478bd9Sstevel@tonic-gate "/proc/%s/object/a.out", pidarg); 7197c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = object; 7207c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = pidarg; 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate /* 7247c478bd9Sstevel@tonic-gate * Find the first argument that is not a special "-" token. If one is 7257c478bd9Sstevel@tonic-gate * found, we will examine this file and make some inferences below. 7267c478bd9Sstevel@tonic-gate */ 7277c478bd9Sstevel@tonic-gate for (c = 0; c < tgt_argc && strcmp(tgt_argv[c], "-") == 0; c++) 7287c478bd9Sstevel@tonic-gate continue; 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate if (c < tgt_argc) { 7317c478bd9Sstevel@tonic-gate Elf32_Ehdr ehdr; 7327c478bd9Sstevel@tonic-gate mdb_io_t *io; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate /* 7357c478bd9Sstevel@tonic-gate * If special "-" tokens preceded an argument, shift the entire 7367c478bd9Sstevel@tonic-gate * argument list to the left to remove the leading "-" args. 7377c478bd9Sstevel@tonic-gate */ 7387c478bd9Sstevel@tonic-gate if (c > 0) { 7397c478bd9Sstevel@tonic-gate bcopy(&tgt_argv[c], tgt_argv, 7407c478bd9Sstevel@tonic-gate sizeof (const char *) * (tgt_argc - c)); 7417c478bd9Sstevel@tonic-gate tgt_argc -= c; 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate /* 7457c478bd9Sstevel@tonic-gate * If we just have an object file name, and that file doesn't 7467c478bd9Sstevel@tonic-gate * exist, and it's a string of digits, infer it to be a 7477c478bd9Sstevel@tonic-gate * sequence number referring to a pair of crash dump files. 7487c478bd9Sstevel@tonic-gate */ 7497c478bd9Sstevel@tonic-gate if (tgt_argc == 1 && access(tgt_argv[0], F_OK) == -1 && 7507c478bd9Sstevel@tonic-gate strisnum(tgt_argv[0])) { 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate size_t len = strlen(tgt_argv[0]) + 8; 7537c478bd9Sstevel@tonic-gate const char *object = tgt_argv[0]; 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate tgt_argv[0] = mdb_alloc(len, UM_SLEEP); 7567c478bd9Sstevel@tonic-gate tgt_argv[1] = mdb_alloc(len, UM_SLEEP); 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate (void) strcpy((char *)tgt_argv[0], "unix."); 7597c478bd9Sstevel@tonic-gate (void) strcat((char *)tgt_argv[0], object); 7607c478bd9Sstevel@tonic-gate (void) strcpy((char *)tgt_argv[1], "vmcore."); 7617c478bd9Sstevel@tonic-gate (void) strcat((char *)tgt_argv[1], object); 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate tgt_argc = 2; 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate /* 7677c478bd9Sstevel@tonic-gate * We need to open the object file in order to determine its 7687c478bd9Sstevel@tonic-gate * ELF class and potentially re-exec ourself. 7697c478bd9Sstevel@tonic-gate */ 7707c478bd9Sstevel@tonic-gate if ((io = mdb_fdio_create_path(NULL, tgt_argv[0], 7717c478bd9Sstevel@tonic-gate O_RDONLY, 0)) == NULL) 7727c478bd9Sstevel@tonic-gate die("failed to open %s", tgt_argv[0]); 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate /* 7757c478bd9Sstevel@tonic-gate * If the target is unknown or is not the rawfile target, do 7767c478bd9Sstevel@tonic-gate * a gelf_check to determine if the file is an ELF file. If 7777c478bd9Sstevel@tonic-gate * it is not and the target is unknown, use the rawfile tgt. 7787c478bd9Sstevel@tonic-gate * Otherwise an ELF-based target is needed, so we must abort. 7797c478bd9Sstevel@tonic-gate */ 7807c478bd9Sstevel@tonic-gate if (tgt_ctor != mdb_rawfile_tgt_create && 7817c478bd9Sstevel@tonic-gate mdb_gelf_check(io, &ehdr, ET_NONE) == -1) { 7827c478bd9Sstevel@tonic-gate if (tgt_ctor != NULL) { 7837c478bd9Sstevel@tonic-gate (void) mdb_gelf_check(io, &ehdr, ET_EXEC); 7847c478bd9Sstevel@tonic-gate mdb_io_destroy(io); 7857c478bd9Sstevel@tonic-gate terminate(1); 7867c478bd9Sstevel@tonic-gate } else 7877c478bd9Sstevel@tonic-gate tgt_ctor = mdb_rawfile_tgt_create; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate mdb_io_destroy(io); 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate if (tgt_ctor == mdb_rawfile_tgt_create) 7937c478bd9Sstevel@tonic-gate goto tcreate; /* skip re-exec and just create target */ 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate /* 7967c478bd9Sstevel@tonic-gate * The object file turned out to be a user core file (ET_CORE), 7977c478bd9Sstevel@tonic-gate * and no other arguments were specified, swap 0 and 1. The 7987c478bd9Sstevel@tonic-gate * proc target will infer the executable for us. 7997c478bd9Sstevel@tonic-gate */ 8007c478bd9Sstevel@tonic-gate if (ehdr.e_type == ET_CORE) { 8017c478bd9Sstevel@tonic-gate tgt_argv[tgt_argc++] = tgt_argv[0]; 8027c478bd9Sstevel@tonic-gate tgt_argv[0] = NULL; 8037c478bd9Sstevel@tonic-gate tgt_ctor = mdb_proc_tgt_create; 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate /* 8077c478bd9Sstevel@tonic-gate * If tgt_argv[1] is filled in, open it up and determine if it 8087c478bd9Sstevel@tonic-gate * is a vmcore file. If it is, gelf_check will fail and we 8097c478bd9Sstevel@tonic-gate * set tgt_ctor to 'kvm'; otherwise we use the default. 8107c478bd9Sstevel@tonic-gate */ 8117c478bd9Sstevel@tonic-gate if (tgt_argc > 1 && strcmp(tgt_argv[1], "-") != 0 && 8127c478bd9Sstevel@tonic-gate tgt_argv[0] != NULL && pidarg == NULL) { 8137c478bd9Sstevel@tonic-gate Elf32_Ehdr chdr; 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate if (access(tgt_argv[1], F_OK) == -1) 8167c478bd9Sstevel@tonic-gate die("failed to access %s", tgt_argv[1]); 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate if ((io = mdb_fdio_create_path(NULL, tgt_argv[1], 8197c478bd9Sstevel@tonic-gate O_RDONLY, 0)) == NULL) 8207c478bd9Sstevel@tonic-gate die("failed to open %s", tgt_argv[1]); 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate if (mdb_gelf_check(io, &chdr, ET_NONE) == -1) 8237c478bd9Sstevel@tonic-gate tgt_ctor = mdb_kvm_tgt_create; 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate mdb_io_destroy(io); 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate /* 8297c478bd9Sstevel@tonic-gate * At this point, we've read the ELF header for either an 8307c478bd9Sstevel@tonic-gate * object file or core into ehdr. If the class does not match 8317c478bd9Sstevel@tonic-gate * ours, attempt to exec the mdb of the appropriate class. 8327c478bd9Sstevel@tonic-gate */ 8337c478bd9Sstevel@tonic-gate #ifdef _LP64 8347c478bd9Sstevel@tonic-gate if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) { 8357c478bd9Sstevel@tonic-gate #else 8367c478bd9Sstevel@tonic-gate if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { 8377c478bd9Sstevel@tonic-gate #endif 8387c478bd9Sstevel@tonic-gate if ((p = strrchr(execname, '/')) == NULL) 8397c478bd9Sstevel@tonic-gate die("cannot determine absolute pathname\n"); 8407c478bd9Sstevel@tonic-gate #ifdef _LP64 8417c478bd9Sstevel@tonic-gate #ifdef __sparc 8427c478bd9Sstevel@tonic-gate (void) strcpy(p, "/../sparcv7/"); 8437c478bd9Sstevel@tonic-gate #else 8447c478bd9Sstevel@tonic-gate (void) strcpy(p, "/../i86/"); 8457c478bd9Sstevel@tonic-gate #endif 8467c478bd9Sstevel@tonic-gate #else 8477c478bd9Sstevel@tonic-gate #ifdef __sparc 8487c478bd9Sstevel@tonic-gate (void) strcpy(p, "/../sparcv9/"); 8497c478bd9Sstevel@tonic-gate #else 8507c478bd9Sstevel@tonic-gate (void) strcpy(p, "/../amd64/"); 8517c478bd9Sstevel@tonic-gate #endif 8527c478bd9Sstevel@tonic-gate #endif 8537c478bd9Sstevel@tonic-gate (void) strcat(p, mdb.m_pname); 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate if (mdb.m_term != NULL) 8567c478bd9Sstevel@tonic-gate (void) IOP_CTL(in_io, TCSETSW, &tios); 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate (void) putenv("_MDB_EXEC=1"); 8597c478bd9Sstevel@tonic-gate (void) execv(execname, argv); 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate /* 8627c478bd9Sstevel@tonic-gate * If execv fails, suppress ENOEXEC. Experience shows 8637c478bd9Sstevel@tonic-gate * the most common reason is that the machine is booted 8647c478bd9Sstevel@tonic-gate * under a 32-bit kernel, in which case it is clearer 8657c478bd9Sstevel@tonic-gate * to only print the message below. 8667c478bd9Sstevel@tonic-gate */ 8677c478bd9Sstevel@tonic-gate if (errno != ENOEXEC) 8687c478bd9Sstevel@tonic-gate warn("failed to exec %s", execname); 8697c478bd9Sstevel@tonic-gate #ifdef _LP64 8707c478bd9Sstevel@tonic-gate die("64-bit %s cannot debug 32-bit program %s\n", 8717c478bd9Sstevel@tonic-gate mdb.m_pname, tgt_argv[0] ? 8727c478bd9Sstevel@tonic-gate tgt_argv[0] : tgt_argv[1]); 8737c478bd9Sstevel@tonic-gate #else 8747c478bd9Sstevel@tonic-gate die("32-bit %s cannot debug 64-bit program %s\n", 8757c478bd9Sstevel@tonic-gate mdb.m_pname, tgt_argv[0] ? 8767c478bd9Sstevel@tonic-gate tgt_argv[0] : tgt_argv[1]); 8777c478bd9Sstevel@tonic-gate #endif 8787c478bd9Sstevel@tonic-gate } 8797c478bd9Sstevel@tonic-gate } 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate tcreate: 8827c478bd9Sstevel@tonic-gate if (tgt_ctor == NULL) 8837c478bd9Sstevel@tonic-gate tgt_ctor = mdb_proc_tgt_create; 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate /* 8867c478bd9Sstevel@tonic-gate * If the debugger state is to be inherited from a previous instance, 8877c478bd9Sstevel@tonic-gate * restore it now prior to path evaluation so that %R is updated. 8887c478bd9Sstevel@tonic-gate */ 8897c478bd9Sstevel@tonic-gate if ((p = getenv(MDB_CONFIG_ENV_VAR)) != NULL) { 8907c478bd9Sstevel@tonic-gate mdb_set_config(p); 8917c478bd9Sstevel@tonic-gate (void) unsetenv(MDB_CONFIG_ENV_VAR); 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate /* 8957c478bd9Sstevel@tonic-gate * Path evaluation part 1: Create the initial module path to allow 8967c478bd9Sstevel@tonic-gate * the target constructor to load a support module. Then expand 8977c478bd9Sstevel@tonic-gate * any command-line arguments that modify the paths. 8987c478bd9Sstevel@tonic-gate */ 8997c478bd9Sstevel@tonic-gate if (Iflag != NULL) 9007c478bd9Sstevel@tonic-gate mdb_set_ipath(Iflag); 9017c478bd9Sstevel@tonic-gate else 9027c478bd9Sstevel@tonic-gate mdb_set_ipath(MDB_DEF_IPATH); 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate if (Lflag != NULL) 9057c478bd9Sstevel@tonic-gate mdb_set_lpath(Lflag); 9067c478bd9Sstevel@tonic-gate else 9077c478bd9Sstevel@tonic-gate mdb_set_lpath(MDB_DEF_LPATH); 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate if (mdb_get_prompt() == NULL && !(mdb.m_flags & MDB_FL_ADB)) 9107c478bd9Sstevel@tonic-gate (void) mdb_set_prompt(MDB_DEF_PROMPT); 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, tgt_argc, tgt_argv); 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate if (tgt == NULL) { 9157c478bd9Sstevel@tonic-gate if (errno == EINVAL) 9167c478bd9Sstevel@tonic-gate usage(2); /* target can return EINVAL to get usage */ 9177c478bd9Sstevel@tonic-gate if (errno == EMDB_TGT) 9187c478bd9Sstevel@tonic-gate terminate(1); /* target already printed error msg */ 9197c478bd9Sstevel@tonic-gate die("failed to initialize target"); 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate mdb_tgt_activate(tgt); 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate mdb_create_loadable_disasms(); 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate if (Vflag != NULL && mdb_dis_select(Vflag) == -1) 9277c478bd9Sstevel@tonic-gate warn("invalid disassembler mode -- %s\n", Vflag); 9287c478bd9Sstevel@tonic-gate 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate if (Rflag && mdb.m_term != NULL) 9317c478bd9Sstevel@tonic-gate warn("Using proto area %s\n", mdb.m_root); 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate /* 9347c478bd9Sstevel@tonic-gate * If the target was successfully constructed and -O was specified, 9357c478bd9Sstevel@tonic-gate * we now attempt to enter piggy-mode for debugging jurassic problems. 9367c478bd9Sstevel@tonic-gate */ 9377c478bd9Sstevel@tonic-gate if (Oflag) { 9387c478bd9Sstevel@tonic-gate pcinfo_t pci; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate (void) strcpy(pci.pc_clname, "RT"); 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate if (priocntl(P_LWPID, P_MYID, PC_GETCID, (caddr_t)&pci) != -1) { 9437c478bd9Sstevel@tonic-gate pcparms_t pcp; 9447c478bd9Sstevel@tonic-gate rtparms_t *rtp = (rtparms_t *)pcp.pc_clparms; 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate rtp->rt_pri = 35; 9477c478bd9Sstevel@tonic-gate rtp->rt_tqsecs = 0; 9487c478bd9Sstevel@tonic-gate rtp->rt_tqnsecs = RT_TQDEF; 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate pcp.pc_cid = pci.pc_cid; 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate if (priocntl(P_LWPID, P_MYID, PC_SETPARMS, 9537c478bd9Sstevel@tonic-gate (caddr_t)&pcp) == -1) { 9547c478bd9Sstevel@tonic-gate warn("failed to set RT parameters"); 9557c478bd9Sstevel@tonic-gate Oflag = 0; 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate } else { 9587c478bd9Sstevel@tonic-gate warn("failed to get RT class id"); 9597c478bd9Sstevel@tonic-gate Oflag = 0; 9607c478bd9Sstevel@tonic-gate } 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) { 9637c478bd9Sstevel@tonic-gate warn("failed to lock address space"); 9647c478bd9Sstevel@tonic-gate Oflag = 0; 9657c478bd9Sstevel@tonic-gate } 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate if (Oflag) 9687c478bd9Sstevel@tonic-gate mdb_printf("%s: oink, oink!\n", mdb.m_pname); 9697c478bd9Sstevel@tonic-gate } 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate /* 9727c478bd9Sstevel@tonic-gate * Path evaluation part 2: Re-evaluate the path now that the target 9737c478bd9Sstevel@tonic-gate * is ready (and thus we have access to the real platform string). 9747c478bd9Sstevel@tonic-gate * Do this before reading ~/.mdbrc to allow path modifications prior 9757c478bd9Sstevel@tonic-gate * to performing module auto-loading. 9767c478bd9Sstevel@tonic-gate */ 9777c478bd9Sstevel@tonic-gate mdb_set_ipath(mdb.m_ipathstr); 9787c478bd9Sstevel@tonic-gate mdb_set_lpath(mdb.m_lpathstr); 9797c478bd9Sstevel@tonic-gate 9807c478bd9Sstevel@tonic-gate if (!Sflag && (p = getenv("HOME")) != NULL) { 9817c478bd9Sstevel@tonic-gate char rcpath[MAXPATHLEN]; 9827c478bd9Sstevel@tonic-gate mdb_io_t *rc_io; 9837c478bd9Sstevel@tonic-gate int fd; 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate (void) mdb_iob_snprintf(rcpath, MAXPATHLEN, "%s/.mdbrc", p); 9867c478bd9Sstevel@tonic-gate fd = open64(rcpath, O_RDONLY); 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate if (fd >= 0 && (rc_io = mdb_fdio_create_named(fd, rcpath))) { 9897c478bd9Sstevel@tonic-gate mdb_iob_t *iob = mdb_iob_create(rc_io, MDB_IOB_RDONLY); 9907c478bd9Sstevel@tonic-gate mdb_iob_t *old = mdb.m_in; 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate mdb.m_in = iob; 9937c478bd9Sstevel@tonic-gate (void) mdb_run(); 9947c478bd9Sstevel@tonic-gate mdb.m_in = old; 9957c478bd9Sstevel@tonic-gate } 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate if (!(mdb.m_flags & MDB_FL_NOMODS)) 9997c478bd9Sstevel@tonic-gate mdb_module_load_all(0); 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate (void) mdb_signal_sethandler(SIGINT, int_handler, NULL); 10027c478bd9Sstevel@tonic-gate while ((status = mdb_run()) == MDB_ERR_ABORT || 10037c478bd9Sstevel@tonic-gate status == MDB_ERR_OUTPUT) { 10047c478bd9Sstevel@tonic-gate /* 10057c478bd9Sstevel@tonic-gate * If a write failed on stdout, give up. A more informative 10067c478bd9Sstevel@tonic-gate * error message will already have been printed by mdb_run(). 10077c478bd9Sstevel@tonic-gate */ 10087c478bd9Sstevel@tonic-gate if (status == MDB_ERR_OUTPUT && 10097c478bd9Sstevel@tonic-gate mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR) { 10107c478bd9Sstevel@tonic-gate mdb_warn("write to stdout failed, exiting\n"); 10117c478bd9Sstevel@tonic-gate break; 10127c478bd9Sstevel@tonic-gate } 10137c478bd9Sstevel@tonic-gate continue; 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate terminate((status == MDB_ERR_QUIT || status == 0) ? 0 : 1); 10177c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 10187c478bd9Sstevel@tonic-gate return (0); 10197c478bd9Sstevel@tonic-gate } 1020