Beispiel #1
0
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);
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
/*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);
	}
}
Beispiel #4
0
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, &reg_disc, MDB_NV_RDONLY);

	mdb_tgt_elf_export(kt->k_file);
}
Beispiel #5
0
/*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);
}