From 9e00d833996fe78d6f0d46d74358950fcec496c7 Mon Sep 17 00:00:00 2001 From: foxostro Date: Tue, 19 Mar 2019 22:17:18 -0700 Subject: [PATCH] PanicKernel prints a backtrace using _Unwind_Backtrace(). --- Kernel/src/platform/i386/panic.cpp | 31 ++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Kernel/src/platform/i386/panic.cpp b/Kernel/src/platform/i386/panic.cpp index 8e621fd..fff7454 100644 --- a/Kernel/src/platform/i386/panic.cpp +++ b/Kernel/src/platform/i386/panic.cpp @@ -4,11 +4,13 @@ #include #include #include -#include // for enumerate_stack_frames() +#include // for _Unwind_* symbols #include #include +static _Unwind_Reason_Code trace(struct _Unwind_Context* context, void* param); + class PanicKernel : private KernelPolicy { public: virtual ~PanicKernel() = default; @@ -17,7 +19,7 @@ class PanicKernel : private KernelPolicy { : message_(message), terminal_(display_) { - hardware_interrupt_controller_.init(/*panic=*/ true); + // hardware_interrupt_controller_.init(/*panic=*/ true); } __attribute__((noreturn)) void run() noexcept @@ -39,14 +41,22 @@ class PanicKernel : private KernelPolicy { void backtrace() { puts("Back Trace:\n"); - enumerate_stack_frames([&](uintptr_t instruction_pointer){ + _Unwind_Backtrace(::trace, reinterpret_cast(this)); + puts("End Back Trace\n"); + } + + _Unwind_Reason_Code trace(struct _Unwind_Context* context) + { + void* ip = reinterpret_cast(_Unwind_GetIP(context)); + if (ip) { char buffer[32] = {0}; - snprintf(buffer, sizeof(buffer), - "[%p]\n", - reinterpret_cast(instruction_pointer)); + snprintf(buffer, sizeof(buffer), "[%p]\n", + reinterpret_cast(ip)); puts(buffer); - }); - puts("End Back Trace\n"); + return _URC_NO_REASON; + } else { + return _URC_END_OF_STACK; + } } __attribute__((noreturn)) void interrupt() noexcept @@ -65,6 +75,11 @@ class PanicKernel : private KernelPolicy { LoggerTextOutputStream logger_; }; +static _Unwind_Reason_Code trace(struct _Unwind_Context* context, void* param) +{ + return reinterpret_cast(param)->trace(context); +} + static PanicKernel* g_panic_kernel; // Prints a message to the screen and halts forever.