static void usage(int status) { mdb_iob_printf(mdb.m_err, "Usage: %s [-fkmuwyAFKMSUW] [+/-o option] " "[-p pid] [-s dist] [-I path] [-L path]\n\t[-P prompt] " "[-R root] [-V dis-version] [object [core] | core | suffix]\n\n", mdb.m_pname); mdb_iob_puts(mdb.m_err, "\t-f force raw file debugging mode\n" "\t-k force kernel debugging mode\n" "\t-m disable demand-loading of module symbols\n" "\t-o set specified debugger option (+o to unset)\n" "\t-p attach to specified process-id\n" "\t-s set symbol matching distance\n" "\t-u force user program debugging mode\n" "\t-w enable write mode\n" "\t-y send terminal initialization sequences for tty mode\n" "\t-A disable automatic loading of mdb modules\n" "\t-F enable forcible takeover mode\n" "\t-K stop operating system and enter live kernel debugger\n" "\t-M preload all module symbols\n" "\t-I set initial path for macro files\n" "\t-L set initial path for module libs\n" "\t-P set command-line prompt\n" "\t-R set root directory for pathname expansion\n" "\t-S suppress processing of ~/.mdbrc file\n" "\t-U unload live kernel debugger\n" "\t-W enable I/O-mapped memory access (kernel only)\n" "\t-V set disassembler version\n"); terminate(status); }
void mdb_dvprintf(uint_t mode, const char *format, va_list alist) { if ((mdb.m_debug & mode) == mode && format != NULL && *format != '\0' && mdb.m_err != NULL) { mdb_iob_puts(mdb.m_err, dbg_prefix); mdb_iob_vprintf(mdb.m_err, format, alist); if (format[strlen(format) - 1] != '\n') mdb_iob_nl(mdb.m_err); } }
/*PRINTFLIKE2*/ void mdb_dprintf(uint_t mode, const char *format, ...) { if ((mdb.m_debug & mode) == mode && mdb.m_err != NULL) { va_list alist; mdb_iob_puts(mdb.m_err, dbg_prefix); va_start(alist, format); mdb_iob_vprintf(mdb.m_err, format, alist); va_end(alist); } }
void kt_activate(mdb_tgt_t *t) { static const mdb_nv_disc_t reg_disc = { NULL, reg_disc_get }; kt_data_t *kt = t->t_data; void *sym; int oflag; mdb_prop_postmortem = (kt->k_dumphdr != NULL); mdb_prop_kernel = TRUE; mdb_prop_datamodel = MDB_TGT_MODEL_NATIVE; if (kt->k_activated == FALSE) { struct utsname u1, u2; /* * If we're examining a crash dump, root is /, and uname(2) * does not match the utsname in the dump, issue a warning. * Note that we are assuming that the modules and macros in * /usr/lib are compiled against the kernel from uname -rv. */ if (mdb_prop_postmortem && strcmp(mdb.m_root, "/") == 0 && uname(&u1) >= 0 && kt_uname(t, &u2) >= 0 && (strcmp(u1.release, u2.release) || strcmp(u1.version, u2.version))) { mdb_warn("warning: dump is from %s %s %s; dcmds and " "macros may not match kernel implementation\n", u2.sysname, u2.release, u2.version); } if (mdb_module_load(KT_MODULE, MDB_MOD_GLOBAL) < 0) { warn("failed to load kernel support module -- " "some modules may not load\n"); } if (mdb_prop_postmortem) { sym = dlsym(RTLD_NEXT, "mdb_dump_print_content"); if (sym != NULL) kt->k_dump_print_content = (void (*)())sym; sym = dlsym(RTLD_NEXT, "mdb_dump_find_curproc"); if (sym != NULL) kt->k_dump_find_curproc = (int (*)())sym; kt->k_dumpcontent = kt_find_dump_contents(kt); } if (t->t_flags & MDB_TGT_F_PRELOAD) { oflag = mdb_iob_getflags(mdb.m_out) & MDB_IOB_PGENABLE; mdb_iob_clrflags(mdb.m_out, oflag); mdb_iob_puts(mdb.m_out, "Preloading module symbols: ["); mdb_iob_flush(mdb.m_out); } if (!(t->t_flags & MDB_TGT_F_NOLOAD)) kt_load_modules(kt, t); if (t->t_flags & MDB_TGT_F_PRELOAD) { mdb_iob_puts(mdb.m_out, " ]\n"); mdb_iob_setflags(mdb.m_out, oflag); } kt->k_activated = TRUE; } (void) mdb_tgt_register_dcmds(t, &kt_dcmds[0], MDB_MOD_FORCE); /* Export some of our registers as named variables */ mdb_tgt_register_regvars(t, kt->k_rds, ®_disc, MDB_NV_RDONLY); mdb_tgt_elf_export(kt->k_file); }
/*ARGSUSED*/ static void * mdb_umem_handler(size_t nbytes, size_t align, uint_t flags) { #ifdef _KMDB /* * kmdb has a fixed, dedicated VA range in which to play. This range * won't change size while the debugger is running, regardless of how * long we wait. As a result, the only sensible course of action is * to fail the request. If we're here, however, the request was made * with UM_SLEEP. The caller is thus not expecting a NULL back. We'll * have to fail the current dcmd set. */ if (mdb.m_depth > 0) { warn("failed to allocate %lu bytes -- recovering\n", (ulong_t)nbytes); kmdb_print_stack(); longjmp(mdb.m_frame->f_pcb, MDB_ERR_NOMEM); } #else /* * mdb, on the other hand, can afford to wait, as someone may actually * free something. */ if (errno == EAGAIN) { void *ptr = NULL; char buf[64]; (void) mdb_iob_snprintf(buf, sizeof (buf), "[ sleeping for %lu bytes of free memory ... ]", (ulong_t)nbytes); (void) mdb_iob_puts(mdb.m_err, buf); (void) mdb_iob_flush(mdb.m_err); do { (void) poll(NULL, 0, 1000); if (align != 0) ptr = memalign(align, nbytes); else ptr = malloc(nbytes); } while (ptr == NULL && errno == EAGAIN); if (ptr != NULL) return (ptr); (void) memset(buf, '\b', strlen(buf)); (void) mdb_iob_puts(mdb.m_err, buf); (void) mdb_iob_flush(mdb.m_err); (void) memset(buf, ' ', strlen(buf)); (void) mdb_iob_puts(mdb.m_err, buf); (void) mdb_iob_flush(mdb.m_err); (void) memset(buf, '\b', strlen(buf)); (void) mdb_iob_puts(mdb.m_err, buf); (void) mdb_iob_flush(mdb.m_err); } #endif die("failed to allocate %lu bytes -- terminating\n", (ulong_t)nbytes); /*NOTREACHED*/ return (NULL); }