Example #1
0
/*ARGSUSED*/
void
exit(int status)
{
#ifdef __sparc
	extern void kmdb_prom_exit_to_mon(void) __NORETURN;

	kmdb_prom_exit_to_mon();
#else
	extern void kmdb_dpi_reboot(void) __NORETURN;
	static int recurse = 0;

	if (!recurse) {

		recurse = 1;

		mdb_iob_printf(mdb.m_out, "Press any key to reboot\n");
		mdb_iob_flush(mdb.m_out);
		mdb_iob_clearlines(mdb.m_out);

		(void) kmdb_getchar();
	}

	kmdb_dpi_reboot();
#endif
}
Example #2
0
/*
 * Called during normal debugger operation and during debugger faults.
 */
static void
kaif_enter_mon(void)
{
	char c;

	for (;;) {
		mdb_iob_printf(mdb.m_out,
		    "%s: Do you really want to reboot? (y/n) ",
		    mdb.m_pname);
		mdb_iob_flush(mdb.m_out);
		mdb_iob_clearlines(mdb.m_out);

		c = kmdb_getchar();

		if (c == 'n' || c == 'N' || c == CTRL('c'))
			return;
		else if (c == 'y' || c == 'Y') {
			mdb_iob_printf(mdb.m_out, "Rebooting...\n");

			kmdb_dpi_reboot();
		}
	}
}
Example #3
0
/*
 * The real main loop of the debugger: create a new execution frame on the
 * debugger stack, and while we have input available, call into the parser.
 */
int
mdb_run(void)
{
	volatile int err;
	mdb_frame_t f;

	mdb_intr_disable();
	mdb_frame_push(&f);

	/*
	 * This is a fresh mdb context, so ignore any pipe command we may have
	 * inherited from the previous frame.
	 */
	f.f_pcmd = NULL;

	if ((err = setjmp(f.f_pcb)) != 0) {
		int pop = (mdb.m_in != NULL &&
		    (mdb_iob_isapipe(mdb.m_in) || mdb_iob_isastr(mdb.m_in)));
		int fromcmd = (f.f_cp != NULL);

		mdb_dprintf(MDB_DBG_DSTK, "frame <%u> caught event %s\n",
		    f.f_id, mdb_err2str(err));

		/*
		 * If a syntax error or other failure has occurred, pop all
		 * input buffers pushed by commands executed in this frame.
		 */
		while (mdb_iob_stack_size(&f.f_istk) != 0) {
			if (mdb.m_in != NULL)
				mdb_iob_destroy(mdb.m_in);
			mdb.m_in = mdb_iob_stack_pop(&f.f_istk);
			yylineno = mdb_iob_lineno(mdb.m_in);
		}

		/*
		 * Reset standard output and the current frame to a known,
		 * clean state, so we can continue execution.
		 */
		mdb_iob_margin(mdb.m_out, MDB_IOB_DEFMARGIN);
		mdb_iob_clrflags(mdb.m_out, MDB_IOB_INDENT);
		mdb_iob_discard(mdb.m_out);
		mdb_frame_reset(&f);

		/*
		 * If there was an error writing to output, display a warning
		 * message if this is the topmost frame.
		 */
		if (err == MDB_ERR_OUTPUT && mdb.m_depth == 1 && errno != EPIPE)
			mdb_warn("write failed");

		/*
		 * If an interrupt or quit signal is reported, we may have been
		 * in the middle of typing or processing the command line:
		 * print a newline and discard everything in the parser's iob.
		 * Note that we do this after m_out has been reset, otherwise
		 * we could trigger a pipe context switch or cause a write
		 * to a broken pipe (in the case of a shell command) when
		 * writing the newline.
		 */
		if (err == MDB_ERR_SIGINT || err == MDB_ERR_QUIT) {
			mdb_iob_nl(mdb.m_out);
			yydiscard();
		}

		/*
		 * If we quit or abort using the output pager, reset the
		 * line count on standard output back to zero.
		 */
		if (err == MDB_ERR_PAGER || MDB_ERR_IS_FATAL(err))
			mdb_iob_clearlines(mdb.m_out);

		/*
		 * If the user requested the debugger quit or abort back to
		 * the top, or if standard input is a pipe or mdb_eval("..."),
		 * then propagate the error up the debugger stack.
		 */
		if (MDB_ERR_IS_FATAL(err) || pop != 0 ||
		    (err == MDB_ERR_PAGER && mdb.m_fmark != &f) ||
		    (err == MDB_ERR_NOMEM && !fromcmd)) {
			mdb_frame_pop(&f, err);
			return (err);
		}

		/*
		 * If we've returned here from a context where signals were
		 * blocked (e.g. a signal handler), we can now unblock them.
		 */
		if (err == MDB_ERR_SIGINT)
			(void) mdb_signal_unblock(SIGINT);
	} else
		mdb_intr_enable();

	for (;;) {
		while (mdb.m_in != NULL && (mdb_iob_getflags(mdb.m_in) &
		    (MDB_IOB_ERR | MDB_IOB_EOF)) == 0) {
			if (mdb.m_depth == 1 &&
			    mdb_iob_stack_size(&f.f_istk) == 0) {
				mdb_iob_clearlines(mdb.m_out);
				mdb_tgt_periodic(mdb.m_target);
			}

			(void) yyparse();
		}

		if (mdb.m_in != NULL) {
			if (mdb_iob_err(mdb.m_in)) {
				warn("error reading input stream %s\n",
				    mdb_iob_name(mdb.m_in));
			}
			mdb_iob_destroy(mdb.m_in);
			mdb.m_in = NULL;
		}

		if (mdb_iob_stack_size(&f.f_istk) == 0)
			break; /* return when we're out of input */

		mdb.m_in = mdb_iob_stack_pop(&f.f_istk);
		yylineno = mdb_iob_lineno(mdb.m_in);
	}

	mdb_frame_pop(&f, 0);

	/*
	 * The value of '.' is a per-frame attribute, to preserve it properly
	 * when switching frames.  But in the case of calling mdb_run()
	 * explicitly (such as through mdb_eval), we want to propagate the value
	 * of '.' to the parent.
	 */
	mdb_nv_set_value(mdb.m_dot, f.f_dot);

	return (0);
}