Browse Source

Kernel: Print panic backtrace to both the screen and serial

Previously it would only print the backtrace to serial, which would be
inaccessible if you don't have serial setup.
Luke 4 years ago
parent
commit
cbbbc38f27
3 changed files with 22 additions and 9 deletions
  1. 15 7
      Kernel/KSyms.cpp
  2. 6 1
      Kernel/KSyms.h
  3. 1 1
      Kernel/Panic.cpp

+ 15 - 7
Kernel/KSyms.cpp

@@ -100,8 +100,16 @@ UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(ReadonlyBytes const&
     g_kernel_symbols_available = true;
 }
 
-NEVER_INLINE static void dump_backtrace_impl(FlatPtr base_pointer, bool use_ksyms)
+NEVER_INLINE static void dump_backtrace_impl(FlatPtr base_pointer, bool use_ksyms, PrintToScreen print_to_screen)
 {
+#define PRINT_LINE(fmtstr, ...)                    \
+    do {                                           \
+        if (print_to_screen == PrintToScreen::No)  \
+            dbgln(fmtstr, __VA_ARGS__);            \
+        else                                       \
+            critical_dmesgln(fmtstr, __VA_ARGS__); \
+    } while (0)
+
     SmapDisabler disabler;
     if (use_ksyms && !g_kernel_symbols_available) {
         Processor::halt();
@@ -133,7 +141,7 @@ NEVER_INLINE static void dump_backtrace_impl(FlatPtr base_pointer, bool use_ksym
         FlatPtr* stack_ptr = (FlatPtr*)base_pointer;
         while (stack_ptr && safe_memcpy(copied_stack_ptr, stack_ptr, sizeof(copied_stack_ptr), fault_at)) {
             FlatPtr retaddr = copied_stack_ptr[1];
-            dbgln("{:p} (next: {:p})", retaddr, stack_ptr ? (FlatPtr*)copied_stack_ptr[0] : 0);
+            PRINT_LINE("{:p} (next: {:p})", retaddr, stack_ptr ? (FlatPtr*)copied_stack_ptr[0] : 0);
             stack_ptr = (FlatPtr*)copied_stack_ptr[0];
         }
         return;
@@ -144,18 +152,18 @@ NEVER_INLINE static void dump_backtrace_impl(FlatPtr base_pointer, bool use_ksym
         if (!symbol.address)
             break;
         if (!symbol.symbol) {
-            dbgln("Kernel + {:p}", symbol.address - kernel_load_base);
+            PRINT_LINE("Kernel + {:p}", symbol.address - kernel_load_base);
             continue;
         }
         size_t offset = symbol.address - symbol.symbol->address;
         if (symbol.symbol->address == g_highest_kernel_symbol_address && offset > 4096)
-            dbgln("Kernel + {:p}", symbol.address - kernel_load_base);
+            PRINT_LINE("Kernel + {:p}", symbol.address - kernel_load_base);
         else
-            dbgln("Kernel + {:p}  {} +{:#x}", symbol.address - kernel_load_base, symbol.symbol->name, offset);
+            PRINT_LINE("Kernel + {:p}  {} +{:#x}", symbol.address - kernel_load_base, symbol.symbol->name, offset);
     }
 }
 
-void dump_backtrace()
+void dump_backtrace(PrintToScreen print_to_screen)
 {
     static bool in_dump_backtrace = false;
     if (in_dump_backtrace)
@@ -165,7 +173,7 @@ void dump_backtrace()
     FlatPtr ebp;
     asm volatile("movl %%ebp, %%eax"
                  : "=a"(ebp));
-    dump_backtrace_impl(ebp, g_kernel_symbols_available);
+    dump_backtrace_impl(ebp, g_kernel_symbols_available, print_to_screen);
 }
 
 UNMAP_AFTER_INIT void load_kernel_symbol_table()

+ 6 - 1
Kernel/KSyms.h

@@ -15,6 +15,11 @@ struct KernelSymbol {
     const char* name;
 };
 
+enum class PrintToScreen {
+    No,
+    Yes,
+};
+
 FlatPtr address_for_kernel_symbol(const StringView& name);
 const KernelSymbol* symbolicate_kernel_address(FlatPtr);
 void load_kernel_symbol_table();
@@ -23,6 +28,6 @@ extern bool g_kernel_symbols_available;
 extern FlatPtr g_lowest_kernel_symbol_address;
 extern FlatPtr g_highest_kernel_symbol_address;
 
-void dump_backtrace();
+void dump_backtrace(PrintToScreen print_to_screen = PrintToScreen::No);
 
 }

+ 1 - 1
Kernel/Panic.cpp

@@ -26,7 +26,7 @@ namespace Kernel {
 void __panic(const char* file, unsigned int line, const char* function)
 {
     critical_dmesgln("at {}:{} in {}", file, line, function);
-    dump_backtrace();
+    dump_backtrace(PrintToScreen::Yes);
     if (kernel_command_line().boot_mode() == BootMode::SelfTest)
         __shutdown();
     else