* 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
This commit is contained in:
parent
976e52595e
commit
2d2b6b1f1a
@ -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
|
static void
|
||||||
kernel_debugger_loop(const char* messagePrefix, const char* message,
|
kernel_debugger_loop(const char* messagePrefix, const char* message,
|
||||||
va_list args, int32 cpu)
|
va_list args, int32 cpu)
|
||||||
@ -802,36 +844,23 @@ kernel_debugger_loop(const char* messagePrefix, const char* message,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_debugger_command("help")) {
|
if (!has_debugger_command("help") || message != NULL) {
|
||||||
// commands are registered already
|
// No commands yet or we came here via a panic(). Always print a stack
|
||||||
if (sCurrentKernelDebuggerMessage != NULL
|
// trace in these cases.
|
||||||
&& strstr(sCurrentKernelDebuggerMessage,
|
debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
|
||||||
kKDLMessageCommandSeparator) != NULL) {
|
&stack_trace_trampoline, 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);
|
|
||||||
|
|
||||||
debug_free(commandBuffer);
|
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
|
||||||
} else {
|
// can't use the keyboard.
|
||||||
// no commands yet -- always print a stack trace at least
|
bool pagingEnabled = blue_screen_paging_enabled();
|
||||||
arch_debug_stack_trace();
|
blue_screen_set_paging(false);
|
||||||
|
|
||||||
|
execute_panic_commands();
|
||||||
|
|
||||||
|
blue_screen_set_paging(pagingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 continuableLine = -1;
|
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
|
static int
|
||||||
cmd_dump_syslog(int argc, char** argv)
|
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",
|
"Reprint the message printed when entering KDL",
|
||||||
"\n"
|
"\n"
|
||||||
"Reprints the message printed when entering KDL.\n", 0);
|
"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();
|
debug_builtin_commands_init();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user