void KernelCrashHandler(struct interrupt_context* intctx)
{
	Scheduler::SaveInterruptedContext(intctx, &CurrentThread()->registers);

	// Panic the kernel with a diagnostic message.
	PanicF("Unhandled CPU Exception id %zu `%s' at ip=0x%zx (cr2=0x%zx, "
	       "err_code=0x%zx)", intctx->int_no, ExceptionName(intctx),
	       ExceptionLocation(intctx), intctx->cr2, intctx->err_code);
}
Example #2
0
 const ExceptionLocation Exception::getLocation(
    const size_t& index) const
    throw()
 {
    if (index < 0 || index>=getLocationCount())
    {
       return ExceptionLocation();
    }
    else
    {
       return locations[index];
    }
 }
void UserCrashHandler(struct interrupt_context* intctx)
{
	Scheduler::SaveInterruptedContext(intctx, &CurrentThread()->registers);

	// Execute this crash handler with preemption on.
	Interrupt::Enable();

	// TODO: Also send signals for other types of user-space crashes.
	if ( intctx->int_no == 14 /* Page fault */ )
	{
		struct sigaction* act = &CurrentProcess()->signal_actions[SIGSEGV];
		kthread_mutex_lock(&CurrentProcess()->signal_lock);
		bool handled = act->sa_handler != SIG_DFL && act->sa_handler != SIG_IGN;
		if ( handled )
			CurrentThread()->DeliverSignalUnlocked(SIGSEGV);
		kthread_mutex_unlock(&CurrentProcess()->signal_lock);
		if ( handled )
		{
			assert(Interrupt::IsEnabled());
			return Signal::DispatchHandler(intctx, NULL);
		}
	}

	// Issue a diagnostic message to the kernel log concerning the crash.
	Log::PrintF("The current process (pid %ji `%s') crashed and was terminated:\n",
	            (intmax_t) CurrentProcess()->pid, CurrentProcess()->program_image_path);
	Log::PrintF("%s exception at ip=0x%zx (cr2=0x%zx, err_code=0x%zx)\n",
	            ExceptionName(intctx), ExceptionLocation(intctx), intctx->cr2,
	            intctx->err_code);

	// Exit the process with the right error code.
	// TODO: Send a SIGINT, SIGBUS, or whatever instead.
	CurrentProcess()->ExitThroughSignal(SIGSEGV);

	// Deliver signals to this thread so it can exit correctly.
	assert(Interrupt::IsEnabled());
	Signal::DispatchHandler(intctx, NULL);
}