summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/CrashHandler.cpp2
-rw-r--r--Kernel/KSyms.cpp3
-rw-r--r--Kernel/Process.cpp18
-rw-r--r--Kernel/Process.h2
-rw-r--r--Kernel/Syscall.cpp2
-rw-r--r--Kernel/Syscalls/thread.cpp2
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) {