Author: bonefish Date: 2010-03-18 17:17:15 +0100 (Thu, 18 Mar 2010) New Revision: 35902 Changeset: http://dev.haiku-os.org/changeset/35902/haiku Modified: haiku/trunk/src/system/kernel/debug/debug.cpp Log: * 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). Modified: haiku/trunk/src/system/kernel/debug/debug.cpp =================================================================== --- haiku/trunk/src/system/kernel/debug/debug.cpp 2010-03-18 16:11:29 UTC (rev 35901) +++ haiku/trunk/src/system/kernel/debug/debug.cpp 2010-03-18 16:17:15 UTC (rev 35902) @@ -748,6 +748,48 @@ 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 @@ } } + 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); + } + 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); + // 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); - debug_free(commandBuffer); - } - } - } else { - // no commands yet -- always print a stack trace at least - arch_debug_stack_trace(); + execute_panic_commands(); + + blue_screen_set_paging(pagingEnabled); } int32 continuableLine = -1; @@ -1004,6 +1033,14 @@ static int +cmd_execute_panic_commands(int argc, char** argv) +{ + execute_panic_commands(); + return 0; +} + + +static int cmd_dump_syslog(int argc, char** argv) { if (!sSyslogOutputEnabled) { @@ -1548,6 +1585,12 @@ "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();