From 2d2b6b1f1ad316c58e6ea5bae74574eb6d15ef52 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 18 Mar 2010 16:17:15 +0000 Subject: [PATCH] * Unconditionally print a stack trace when we entered KDL via panic(). * Print the initial stack trace safely, i.e. in a setjmp() + fault handler environment. * Disable pagination while executing the executing the panic() commands. This way even when it is not possible to use the keyboard we get the full output. * Added "panic_commands" kernel debugger command, to execute the panic() commands again (with pagination enabled). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35902 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/debug/debug.cpp | 101 +++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index e0f955c623..3a309f63f9 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -747,6 +747,48 @@ print_kernel_debugger_message() } +static void +execute_panic_commands() +{ + if (sCurrentKernelDebuggerMessage == NULL + || strstr(sCurrentKernelDebuggerMessage, + kKDLMessageCommandSeparator) == NULL) { + return; + } + + // Indeed there are commands to execute. + const size_t kCommandBufferSize = 512; + char* commandBuffer = (char*)debug_malloc(kCommandBufferSize); + if (commandBuffer != NULL) { + va_list tempArgs; + va_copy(tempArgs, sCurrentKernelDebuggerMessageArgs); + + if (vsnprintf(commandBuffer, kCommandBufferSize, + sCurrentKernelDebuggerMessage, tempArgs) + < (int)kCommandBufferSize) { + const char* commands = strstr(commandBuffer, + kKDLMessageCommandSeparator); + if (commands != NULL) { + commands += strlen(kKDLMessageCommandSeparator); + kprintf("initial commands: %s\n", commands); + evaluate_debug_command(commands); + } + } + + va_end(tempArgs); + + debug_free(commandBuffer); + } +} + + +static void +stack_trace_trampoline(void*) +{ + arch_debug_stack_trace(); +} + + static void kernel_debugger_loop(const char* messagePrefix, const char* message, va_list args, int32 cpu) @@ -802,36 +844,23 @@ kernel_debugger_loop(const char* messagePrefix, const char* message, } } - if (has_debugger_command("help")) { - // commands are registered already - if (sCurrentKernelDebuggerMessage != NULL - && strstr(sCurrentKernelDebuggerMessage, - kKDLMessageCommandSeparator) != NULL) { - // The panic() message specifies commands to execute. - const size_t kCommandBufferSize = 512; - char* commandBuffer = (char*)debug_malloc(kCommandBufferSize); - if (commandBuffer != NULL) { - va_list tempArgs; - va_copy(tempArgs, sCurrentKernelDebuggerMessageArgs); - if (vsnprintf(commandBuffer, kCommandBufferSize, - sCurrentKernelDebuggerMessage, tempArgs) - < (int)kCommandBufferSize) { - const char* commands = strstr(commandBuffer, - kKDLMessageCommandSeparator); - if (commands != NULL) { - commands += strlen(kKDLMessageCommandSeparator); - kprintf("initial commands: %s\n", commands); - evaluate_debug_command(commands); - } - } - va_end(tempArgs); + if (!has_debugger_command("help") || message != NULL) { + // No commands yet or we came here via a panic(). Always print a stack + // trace in these cases. + debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer, + &stack_trace_trampoline, NULL); + } - debug_free(commandBuffer); - } - } - } else { - // no commands yet -- always print a stack trace at least - arch_debug_stack_trace(); + if (has_debugger_command("help")) { + // Commands are registered already -- execute panic() commands. Do that + // with paging disabled, so everything is printed, even if the user + // can't use the keyboard. + bool pagingEnabled = blue_screen_paging_enabled(); + blue_screen_set_paging(false); + + execute_panic_commands(); + + blue_screen_set_paging(pagingEnabled); } int32 continuableLine = -1; @@ -1003,6 +1032,14 @@ cmd_dump_kdl_message(int argc, char** argv) } +static int +cmd_execute_panic_commands(int argc, char** argv) +{ + execute_panic_commands(); + return 0; +} + + static int cmd_dump_syslog(int argc, char** argv) { @@ -1548,6 +1585,12 @@ debug_init_post_vm(kernel_args* args) "Reprint the message printed when entering KDL", "\n" "Reprints the message printed when entering KDL.\n", 0); + add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands, + "Execute commands associated with the panic() that caused " + "entering KDL", + "\n" + "Executes the commands associated with the panic() that caused " + "entering KDL.\n", 0); debug_builtin_commands_init();