Пример #1
0
void
vfail(const char *format, va_list alist)
{
	extern const char *volatile _mdb_abort_str;
	static char buf[256];
	static int nfail;

	if (_mdb_abort_str == NULL) {
		_mdb_abort_str = buf; /* Do this first so we don't recurse */
		(void) mdb_iob_vsnprintf(buf, sizeof (buf), format, alist);

		nfail = 1;
	}

	/*
	 * We'll try to print failure messages twice.  Any more than that,
	 * and we're probably hitting an assertion or some other problem in
	 * the printing routines, and will recurse until we run out of stack.
	 */
	if (nfail++ < 3) {
		mdb_iob_printf(mdb.m_err, "%s ABORT: ", mdb.m_pname);
		mdb_iob_vprintf(mdb.m_err, format, alist);
		mdb_iob_flush(mdb.m_err);

		(void) mdb_signal_blockall();
		(void) mdb_signal_raise(SIGABRT);
		(void) mdb_signal_unblock(SIGABRT);
	}

	exit(1);
}
Пример #2
0
/*ARGSUSED*/
static void
flt_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data)
{
	static const struct rlimit rl = {
		(rlim_t)RLIM_INFINITY, (rlim_t)RLIM_INFINITY
	};

	const mdb_idcmd_t *idcp = NULL;

	if (mdb.m_frame != NULL && mdb.m_frame->f_cp != NULL)
		idcp = mdb.m_frame->f_cp->c_dcmd;

	if (sip != NULL)
		bcopy(sip, &_mdb_abort_info, sizeof (_mdb_abort_info));
	if (ucp != NULL)
		bcopy(ucp, &_mdb_abort_ctx, sizeof (_mdb_abort_ctx));

	_mdb_abort_info.si_signo = sig;
	(void) mdb_signal_sethandler(sig, SIG_DFL, NULL);

	/*
	 * If there is no current dcmd, or the current dcmd comes from a
	 * builtin module, we don't allow resume and always core dump.
	 */
	if (idcp == NULL || idcp->idc_modp == NULL ||
	    idcp->idc_modp == &mdb.m_rmod || idcp->idc_modp->mod_hdl == NULL)
		goto dump;

	if (mdb.m_term != NULL) {
		struct frame *fr = (struct frame *)
		    (ucp->uc_mcontext.gregs[STACK_REGISTER] + STACK_BIAS);

		char signame[SIG2STR_MAX];
		int i = 1;
		char c;

		if (sig2str(sig, signame) == -1) {
			mdb_iob_printf(mdb.m_err,
			    "\n*** %s: received signal %d at:\n",
			    mdb.m_pname, sig);
		} else {
			mdb_iob_printf(mdb.m_err,
			    "\n*** %s: received signal %s at:\n",
			    mdb.m_pname, signame);
		}

		if (ucp->uc_mcontext.gregs[REG_PC] != 0)
			print_frame(ucp->uc_mcontext.gregs[REG_PC], i++);

		while (fr != NULL && valid_frame(fr) && fr->fr_savpc != 0) {
			print_frame(fr->fr_savpc, i++);
			fr = (struct frame *)
			    ((uintptr_t)fr->fr_savfp + STACK_BIAS);
		}

query:
		mdb_iob_printf(mdb.m_err, "\n%s: (c)ore dump, (q)uit, "
		    "(r)ecover, or (s)top for debugger [cqrs]? ", mdb.m_pname);

		mdb_iob_flush(mdb.m_err);

		for (;;) {
			if (IOP_READ(mdb.m_term, &c, sizeof (c)) != sizeof (c))
				goto dump;

			switch (c) {
			case 'c':
			case 'C':
				(void) setrlimit(RLIMIT_CORE, &rl);
				mdb_iob_printf(mdb.m_err, "\n%s: attempting "
				    "to dump core ...\n", mdb.m_pname);
				goto dump;

			case 'q':
			case 'Q':
				mdb_iob_discard(mdb.m_out);
				mdb_iob_nl(mdb.m_err);
				(void) mdb_signal_unblockall();
				terminate(1);
				/*NOTREACHED*/

			case 'r':
			case 'R':
				mdb_iob_printf(mdb.m_err, "\n%s: unloading "
				    "module '%s' ...\n", mdb.m_pname,
				    idcp->idc_modp->mod_name);

				(void) mdb_module_unload(
				    idcp->idc_modp->mod_name, 0);

				(void) mdb_signal_sethandler(sig,
				    flt_handler, NULL);

				_mdb_abort_rcount++;
				mdb.m_intr = 0;
				mdb.m_pend = 0;

				(void) mdb_signal_unblockall();
				longjmp(mdb.m_frame->f_pcb, MDB_ERR_ABORT);
				/*NOTREACHED*/

			case 's':
			case 'S':
				mdb_iob_printf(mdb.m_err, "\n%s: "
				    "attempting to stop pid %d ...\n",
				    mdb.m_pname, (int)getpid());

				/*
				 * Stop ourself; if this fails or we are
				 * subsequently continued, ask again.
				 */
				(void) mdb_signal_raise(SIGSTOP);
				(void) mdb_signal_unblockall();
				goto query;
			}
		}
	}

dump:
	if (SI_FROMUSER(sip)) {
		(void) mdb_signal_block(sig);
		(void) mdb_signal_raise(sig);
	}

	(void) sigfillset(&ucp->uc_sigmask);
	(void) sigdelset(&ucp->uc_sigmask, sig);

	if (_mdb_abort_str == NULL)
		_mdb_abort_str = "fatal signal received";

	ucp->uc_flags |= UC_SIGMASK;
	(void) setcontext(ucp);
}