kernel: Show stack traces on page faults + crash the process instead of the whole system on GPFs
This commit is contained in:
parent
0b553cadc0
commit
7efc3a6ea1
@ -80,6 +80,8 @@ void decode_page_fault_error_code(u64 code)
|
||||
|
||||
decode_page_fault_error_code(regs->error);
|
||||
|
||||
CPU::print_stack_trace_at(regs);
|
||||
|
||||
if (!is_in_kernel(regs))
|
||||
{
|
||||
// FIXME: Kill this process with SIGSEGV once we have signals and all that.
|
||||
@ -105,8 +107,6 @@ void decode_page_fault_error_code(u64 code)
|
||||
unreachable();
|
||||
}
|
||||
|
||||
CPU::print_stack_trace_at(regs);
|
||||
|
||||
CPU::efficient_halt();
|
||||
}
|
||||
|
||||
@ -118,6 +118,31 @@ void decode_page_fault_error_code(u64 code)
|
||||
|
||||
CPU::print_stack_trace_at(regs);
|
||||
|
||||
if (!is_in_kernel(regs))
|
||||
{
|
||||
// FIXME: Kill this process with SIGSEGV once we have signals and all that.
|
||||
kerrorln("Current task %zu was terminated because of a general protection fault", Scheduler::current()->id);
|
||||
if (Scheduler::current()->is_kernel) Scheduler::current()->state = ThreadState::Dying;
|
||||
else
|
||||
{
|
||||
auto* current = Scheduler::current();
|
||||
auto* parent = current->parent;
|
||||
if (parent && parent->state == ThreadState::Waiting)
|
||||
{
|
||||
auto child = *parent->child_being_waited_for;
|
||||
if (child == -1 || child == (pid_t)current->id)
|
||||
{
|
||||
parent->child_being_waited_for = (pid_t)current->id;
|
||||
parent->wake_up();
|
||||
}
|
||||
}
|
||||
current->state = ThreadState::Exited;
|
||||
}
|
||||
Scheduler::current()->status = 127;
|
||||
kernel_yield();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
CPU::efficient_halt();
|
||||
}
|
||||
|
||||
@ -302,14 +327,14 @@ namespace CPU
|
||||
asm volatile("hlt");
|
||||
}
|
||||
|
||||
[[noreturn]] void efficient_halt() // Halt the CPU, using the lowest power possible. On x86-64 we do this using the
|
||||
// "hlt" instruction, which puts the CPU into a low-power idle state until the
|
||||
// next interrupt arrives... and we disable interrupts beforehand.
|
||||
[[noreturn]] void efficient_halt() // Halt the CPU, using the lowest power possible. On x86-64 we do this using
|
||||
// the "hlt" instruction, which puts the CPU into a low-power idle state
|
||||
// until the next interrupt arrives... and we disable interrupts beforehand.
|
||||
{
|
||||
asm volatile("cli"); // Disable interrupts
|
||||
loop:
|
||||
asm volatile("hlt"); // Let the cpu rest and pause until the next interrupt arrives... which in this case should
|
||||
// be never (unless an NMI arrives) :)
|
||||
asm volatile("hlt"); // Let the cpu rest and pause until the next interrupt arrives... which in this case
|
||||
// should be never (unless an NMI arrives) :)
|
||||
goto loop; // Safeguard: if we ever wake up, start our low-power rest again
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user