diff options
-rw-r--r-- | Kernel/CrashHandler.cpp | 2 | ||||
-rw-r--r-- | Kernel/KSyms.cpp | 3 | ||||
-rw-r--r-- | Kernel/Process.cpp | 18 | ||||
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/thread.cpp | 2 |
6 files changed, 23 insertions, 6 deletions
diff --git a/Kernel/CrashHandler.cpp b/Kernel/CrashHandler.cpp index 1e0af3d184..f0780827c7 100644 --- a/Kernel/CrashHandler.cpp +++ b/Kernel/CrashHandler.cpp @@ -39,7 +39,7 @@ void handle_crash(Kernel::RegisterState const& regs, char const* description, in PANIC("Crash in kernel"); } - process.crash(signal, regs.ip(), out_of_memory); + process.crash(signal, { regs }, out_of_memory); } } diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index 75be3dbdbd..b3cf6fad46 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -173,7 +173,8 @@ NEVER_INLINE static void dump_backtrace_impl(FlatPtr base_pointer, bool use_ksym void dump_backtrace_from_base_pointer(FlatPtr base_pointer) { - dump_backtrace_impl(base_pointer, g_kernel_symbols_available, PrintToScreen::Yes); + // FIXME: Change signature of dump_backtrace_impl to use an enum instead of a bool. + dump_backtrace_impl(base_pointer, /*use_ksym=*/false, PrintToScreen::No); } void dump_backtrace(PrintToScreen print_to_screen) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 400a7bdab4..637078463a 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -456,11 +456,13 @@ void create_signal_trampoline() g_signal_trampoline_region->remap(); } -void Process::crash(int signal, FlatPtr ip, bool out_of_memory) +void Process::crash(int signal, Optional<RegisterState const&> regs, bool out_of_memory) { VERIFY(!is_dead()); VERIFY(&Process::current() == this); + auto ip = regs.has_value() ? regs->ip() : 0; + if (out_of_memory) { dbgln("\033[31;1mOut of memory\033[m, killing: {}", *this); } else { @@ -470,6 +472,20 @@ void Process::crash(int signal, FlatPtr ip, bool out_of_memory) } else { dbgln("\033[31;1m{:p} (?)\033[0m\n", ip); } +#if ARCH(X86_64) + constexpr bool userspace_backtrace = false; +#elif ARCH(AARCH64) + constexpr bool userspace_backtrace = true; +#else +# error "Unknown architecture" +#endif + if constexpr (userspace_backtrace) { + dbgln("Userspace backtrace:"); + auto bp = regs.has_value() ? regs->bp() : 0; + dump_backtrace_from_base_pointer(bp); + } + + dbgln("Kernel backtrace:"); dump_backtrace(); } with_mutable_protected_data([&](auto& protected_data) { diff --git a/Kernel/Process.h b/Kernel/Process.h index 6b9e0cd605..de02fdc64a 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -456,7 +456,7 @@ public: static void initialize(); - [[noreturn]] void crash(int signal, FlatPtr ip, bool out_of_memory = false); + [[noreturn]] void crash(int signal, Optional<RegisterState const&> regs, bool out_of_memory = false); [[nodiscard]] siginfo_t wait_info() const; const TTY* tty() const { return m_tty; } diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 3ed9c2e874..7410d1f74a 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -183,7 +183,7 @@ NEVER_INLINE void syscall_handler(TrapFrame* trap) if (result.is_error() && result.error().code() == EPROMISEVIOLATION) { VERIFY(current_thread->is_promise_violation_pending()); current_thread->set_promise_violation_pending(false); - process.crash(SIGABRT, 0); + process.crash(SIGABRT, {}); } else { VERIFY(!current_thread->is_promise_violation_pending()); } diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index 72c2ca2354..c01bd0b730 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -86,7 +86,7 @@ void Process::sys$exit_thread(Userspace<void*> exit_value, Userspace<void*> stac auto result = require_promise(Pledge::thread); if (result.is_error()) { // Crash now, as we will never reach back to the syscall handler. - crash(SIGABRT, 0); + crash(SIGABRT, {}); } if (this->thread_count() == 1) { |