mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Kernel: Add optional userspace backtrace to Process::crash
This is very useful for debugging the initial userspace applications, as the CrashReporter is not yet running.
This commit is contained in:
parent
3611427ce2
commit
3295137224
6 changed files with 23 additions and 6 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue