From 3cec75dc33dd1cda148e057d91b48989f6f3a0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 31 Jan 2008 12:25:43 +0000 Subject: [PATCH] * Debugger modules now have two methods: enter_debugger() and exit_debugger(). * The kernel now opens up to 8 debugger modules (and puts them into an array; maybe we'll want to switch to a doubly linked list when there is the need). * Implemented an example debugger module that prints a stack trace of the current thread when the kernel debugger is entered (not included in the image). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23794 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/debug.h | 13 ++++- src/add-ons/kernel/debugger/Jamfile | 1 + .../kernel/debugger/auto_stack_trace/Jamfile | 7 +++ .../auto_stack_trace/auto_stack_trace.cpp | 41 ++++++++++++++ src/add-ons/kernel/debugger/hangman/Jamfile | 2 +- src/add-ons/kernel/debugger/hangman/hangman.c | 53 +++++++++++-------- src/system/kernel/debug/debug.cpp | 40 +++++++++++--- 7 files changed, 125 insertions(+), 32 deletions(-) create mode 100644 src/add-ons/kernel/debugger/auto_stack_trace/Jamfile create mode 100644 src/add-ons/kernel/debugger/auto_stack_trace/auto_stack_trace.cpp diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 726673833d..f9ea4196b8 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de * Distributed under the terms of the Haiku License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -10,6 +10,8 @@ #include +#include + #define KDEBUG 1 @@ -18,7 +20,7 @@ * The kernel debug level. * Level 1 is usual asserts, > 1 should be used for very expensive runtime checks */ -#define KDEBUG 1 +# define KDEBUG 1 #endif #define ASSERT_ALWAYS(x) \ @@ -42,6 +44,13 @@ #define B_KDEBUG_DONT_PARSE_ARGUMENTS (0x01) +struct debugger_module_info { + module_info info; + + void (*enter_debugger)(void); + void (*exit_debugger)(void); +}; + extern int dbg_register_file[B_MAX_CPU_COUNT][14]; #ifdef __cplusplus diff --git a/src/add-ons/kernel/debugger/Jamfile b/src/add-ons/kernel/debugger/Jamfile index 34e1521c1c..2bfefb573e 100644 --- a/src/add-ons/kernel/debugger/Jamfile +++ b/src/add-ons/kernel/debugger/Jamfile @@ -1,3 +1,4 @@ SubDir HAIKU_TOP src add-ons kernel debugger ; +SubInclude HAIKU_TOP src add-ons kernel debugger auto_stack_trace ; SubInclude HAIKU_TOP src add-ons kernel debugger hangman ; diff --git a/src/add-ons/kernel/debugger/auto_stack_trace/Jamfile b/src/add-ons/kernel/debugger/auto_stack_trace/Jamfile new file mode 100644 index 0000000000..f792a8f52e --- /dev/null +++ b/src/add-ons/kernel/debugger/auto_stack_trace/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src add-ons kernel debugger auto_stack_trace ; + +UsePrivateHeaders kernel ; + +KernelAddon auto_stack_trace : + auto_stack_trace.cpp + ; diff --git a/src/add-ons/kernel/debugger/auto_stack_trace/auto_stack_trace.cpp b/src/add-ons/kernel/debugger/auto_stack_trace/auto_stack_trace.cpp new file mode 100644 index 0000000000..f26d541391 --- /dev/null +++ b/src/add-ons/kernel/debugger/auto_stack_trace/auto_stack_trace.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de + * Distributed under the terms of the MIT License. + */ + + +#include + + +static void +enter_debugger(void) +{ + evaluate_debug_command("sc"); +} + + +static status_t +std_ops(int32 op, ...) +{ + if (op == B_MODULE_INIT || op == B_MODULE_UNINIT) + return B_OK; + + return B_BAD_VALUE; +} + + +static struct debugger_module_info sModuleInfo = { + { + "debugger/auto_stack_trace/v1", + 0, + &std_ops + }, + enter_debugger, + NULL +}; + +module_info *modules[] = { + (module_info *)&sModuleInfo, + NULL +}; + diff --git a/src/add-ons/kernel/debugger/hangman/Jamfile b/src/add-ons/kernel/debugger/hangman/Jamfile index 62036adcca..1f07266e44 100644 --- a/src/add-ons/kernel/debugger/hangman/Jamfile +++ b/src/add-ons/kernel/debugger/hangman/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel debugger hangman ; SetSubDirSupportedPlatformsBeOSCompatible ; # UsePrivateHeaders drivers ; -# UsePrivateHeaders kernel ; +UsePrivateHeaders kernel ; KernelAddon hangman : diff --git a/src/add-ons/kernel/debugger/hangman/hangman.c b/src/add-ons/kernel/debugger/hangman/hangman.c index 6cdb00def0..dedb7462e0 100644 --- a/src/add-ons/kernel/debugger/hangman/hangman.c +++ b/src/add-ons/kernel/debugger/hangman/hangman.c @@ -1,8 +1,10 @@ #ifdef _KERNEL_MODE -#include -#include -#include +# include +# include +# include +# include #endif + #include #include #include @@ -440,37 +442,44 @@ find_device(const char *name) # else /* as module */ -status_t std_ops(int32 op, ...); - -status_t +static status_t std_ops(int32 op, ...) { status_t err; switch (op) { - case B_MODULE_INIT: - err = init_words(FORTUNE_FILE); - if (err < B_OK) { - dprintf("hangman: error reading fortune file: %s\n", strerror(err)); - return B_ERROR; - } - add_debugger_command("kdlhangman", kdlhangman, KCMD_HELP); - return B_OK; - case B_MODULE_UNINIT: - remove_debugger_command("kdlhangman", kdlhangman); - return B_ERROR; + case B_MODULE_INIT: + err = init_words(FORTUNE_FILE); + if (err < B_OK) { + dprintf("hangman: error reading fortune file: %s\n", + strerror(err)); + return B_ERROR; + } + add_debugger_command("kdlhangman", kdlhangman, KCMD_HELP); + return B_OK; + case B_MODULE_UNINIT: + remove_debugger_command("kdlhangman", kdlhangman); + return B_OK; } + return B_ERROR; } -static module_info minfo = { - "debugger/hangman/v1", - B_KEEP_LOADED, - &std_ops +static struct debugger_module_info sModuleInfo = { + { + "debugger/hangman/v1", + B_KEEP_LOADED, + &std_ops + }, + NULL, + NULL }; -module_info *modules[] = { &minfo, NULL }; +module_info *modules[] = { + (module_info *)&sModuleInfo, + NULL +}; # endif /* AS_DRIVER */ diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index af6fc8d08c..20bc25db29 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -74,6 +74,10 @@ static int64 sMessageRepeatFirstTime = 0; static int64 sMessageRepeatLastTime = 0; static int32 sMessageRepeatCount = 0; +static debugger_module_info *sDebuggerModules[8]; +static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules) + / sizeof(sDebuggerModules[0]); + #define LINE_BUFFER_SIZE 1024 #define HISTORY_SIZE 16 @@ -850,6 +854,23 @@ err1: } +void +call_modules_hook(bool enter) +{ + uint32 index = 0; + while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) { + debugger_module_info *module = sDebuggerModules[index]; + + if (enter && module->enter_debugger != NULL) + module->enter_debugger(); + else if (!enter && module->exit_debugger != NULL) + module->exit_debugger(); + + index++; + } +} + + // #pragma mark - private kernel API @@ -995,17 +1016,19 @@ debug_init_post_modules(struct kernel_args *args) // load kernel debugger addons cookie = open_module_list("debugger"); - while (true) { + uint32 count = 0; + while (count < kMaxDebuggerModules) { char name[B_FILE_NAME_LENGTH]; size_t nameLength = sizeof(name); - module_info *module; if (read_next_module_name(cookie, name, &nameLength) != B_OK) break; - if (get_module(name, &module) == B_OK) - dprintf("kernel debugger extention \"%s\": loaded\n", name); - else - dprintf("kernel debugger extention \"%s\": failed to load\n", name); + + if (get_module(name, (module_info **)&sDebuggerModules[count]) == B_OK) { + dprintf("kernel debugger extension \"%s\": loaded\n", name); + count++; + } else + dprintf("kernel debugger extension \"%s\": failed to load\n", name); } close_module_list(cookie); @@ -1093,8 +1116,11 @@ kernel_debugger(const char *message) // sort the commands sort_debugger_commands(); + call_modules_hook(true); + kernel_debugger_loop(); + call_modules_hook(false); set_dprintf_enabled(dprintfState); sBlueScreenEnabled = false;