From 91d35b5f621e8c742936604a0cb69ed372e56e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 11 Nov 2003 03:07:53 +0000 Subject: [PATCH] Removed dbg_set_serial_debug() - there is now only set_dprintf_enabled(). Disabled dbg_get_serial_debug(); it's only used temporarily in the keyboard device (and I removed its usage there, too). Added "continue", "exit", and "es" commands as in the Be kernel debugger (they will all exit the debugger and try to continue normal kernel execution). Reordered the sources so that public kernel API is together. Added a _user_debug_output() syscall (not yet activated) which dumps to the kernel's serial output. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5305 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/debug.c | 399 +++++++++++++++++++++------------------- src/kernel/core/main.c | 2 +- 2 files changed, 211 insertions(+), 190 deletions(-) diff --git a/src/kernel/core/debug.c b/src/kernel/core/debug.c index 1f6cf553f8..32a5c1bc26 100644 --- a/src/kernel/core/debug.c +++ b/src/kernel/core/debug.c @@ -26,22 +26,20 @@ #include -int dbg_register_file[2][14]; /* XXXmpetit -- must be made generic */ - - -static bool serial_debug_on = false; -static spinlock dbg_spinlock = 0; -static int debugger_on_cpu = -1; - -struct debugger_command -{ +struct debugger_command { struct debugger_command *next; int (*func)(int, char **); const char *name; const char *description; }; -static struct debugger_command *commands; +int dbg_register_file[2][14]; /* XXXmpetit -- must be made generic */ + +static bool sSerialDebugEnabled = false; +static spinlock dbg_spinlock = 0; +static int debugger_on_cpu = -1; + +static struct debugger_command *sCommands; #define LINE_BUF_SIZE 1024 #define MAX_ARGS 16 @@ -199,7 +197,7 @@ debug_parse_line(char *buf, char **argv, int *argc, int max_args) static void -kernel_debugger_loop() +kernel_debugger_loop(void) { int argc; struct debugger_command *cmd; @@ -212,7 +210,7 @@ kernel_debugger_loop() cmd = NULL; - for(;;) { + for (;;) { dprintf("kdebug> "); debug_read_line(line_buf[cur_line], LINE_BUF_SIZE); debug_parse_line(line_buf[cur_line], args, &argc, MAX_ARGS); @@ -226,27 +224,25 @@ kernel_debugger_loop() if (argc > 0) { // search command by name - cmd = commands; + cmd = sCommands; while (cmd != NULL) { if (strcmp(args[0], cmd->name) == 0) break; cmd = cmd->next; - }; - }; + } + } if (cmd == NULL) dprintf("unknown command, enter \"help\" to get a list of all supported commands\n"); else { - int rc; - - rc = cmd->func(argc, args); + int rc = cmd->func(argc, args); if (rc == B_KDEBUG_QUIT) break; // okay, exit now. if (rc != B_KDEBUG_CONT) cmd = NULL; // forget last command executed... - }; + } cur_line++; if (cur_line >= HISTORY_SIZE) @@ -257,18 +253,166 @@ kernel_debugger_loop() } -void -kernel_debugger(const char * message) +char +dbg_putch(char c) { - arch_dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0])); + char ret; + cpu_status state = disable_interrupts(); + acquire_spinlock(&dbg_spinlock); - if (message) { - dprintf(message); - dprintf("\n"); - }; + if (sSerialDebugEnabled) + ret = arch_dbg_con_putch(c); + else + ret = c; - dprintf("Welcome to Kernel Debugging Land...\n"); - kernel_debugger_loop(); + release_spinlock(&dbg_spinlock); + restore_interrupts(state); + + return ret; +} + + +void +dbg_puts(const char *s) +{ + cpu_status state = disable_interrupts(); + acquire_spinlock(&dbg_spinlock); + + if (sSerialDebugEnabled) + arch_dbg_con_puts(s); + + release_spinlock(&dbg_spinlock); + restore_interrupts(state); +} + + +static int +cmd_reboot(int argc, char **argv) +{ + reboot(); + return 0; // I'll be really suprised if this line ever run! ;-) +} + + +static int +cmd_help(int argc, char **argv) +{ + struct debugger_command *cmd; + + dprintf("debugger commands:\n"); + cmd = sCommands; + while (cmd != NULL) { + dprintf(" %-32s\t\t%s\n", cmd->name, cmd->description ? cmd->description : ""); + cmd = cmd->next; + } + + return 0; +} + + +static int +cmd_continue(int argc, char **argv) +{ + return B_KDEBUG_QUIT; +} + + +int +dbg_init(kernel_args *ka) +{ + sCommands = NULL; + + return arch_dbg_con_init(ka); +} + + +int +dbg_init2(kernel_args *ka) +{ + add_debugger_command("help", &cmd_help, "List all debugger commands"); + add_debugger_command("reboot", &cmd_reboot, "Reboot the system"); + add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); + add_debugger_command("continue", &cmd_continue, "Leave kernel debugger"); + add_debugger_command("exit", &cmd_continue, NULL); + add_debugger_command("es", &cmd_continue, NULL); + + return arch_dbg_init(ka); +} + +// ToDo: this one is probably not needed +#if 0 +bool +dbg_get_serial_debug() +{ + return sSerialDebugEnabled; +} +#endif + +// #pragma mark - +// public API + + +int +add_debugger_command(char *name, int (*func)(int, char **), char *desc) +{ + cpu_status state; + struct debugger_command *cmd; + + cmd = (struct debugger_command *)malloc(sizeof(struct debugger_command)); + if (cmd == NULL) + return ENOMEM; + + cmd->func = func; + cmd->name = name; + cmd->description = desc; + + state = disable_interrupts(); + acquire_spinlock(&dbg_spinlock); + + cmd->next = sCommands; + sCommands = cmd; + + release_spinlock(&dbg_spinlock); + restore_interrupts(state); + + return B_NO_ERROR; +} + + +int +remove_debugger_command(char * name, int (*func)(int, char **)) +{ + struct debugger_command *cmd = sCommands; + struct debugger_command *prev = NULL; + cpu_status state; + + state = disable_interrupts(); + acquire_spinlock(&dbg_spinlock); + + while (cmd) { + if (!strcmp(cmd->name, name) && cmd->func == func) + break; + + prev = cmd; + cmd = cmd->next; + } + + if (cmd) { + if (cmd == sCommands) + sCommands = cmd->next; + else + prev->next = cmd->next; + } + + release_spinlock(&dbg_spinlock); + restore_interrupts(state); + + if (cmd) { + free(cmd); + return B_NO_ERROR; + } + + return B_NAME_NOT_FOUND; } @@ -285,7 +429,7 @@ panic(const char *fmt, ...) // XXX should be renamed? kernel_startup = true; - dbg_set_serial_debug(true); + set_dprintf_enabled(true); state = disable_interrupts(); @@ -309,13 +453,38 @@ panic(const char *fmt, ...) } +void +kernel_debugger(const char * message) +{ + arch_dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0])); + + if (message) { + dprintf(message); + dprintf("\n"); + }; + + dprintf("Welcome to Kernel Debugging Land...\n"); + kernel_debugger_loop(); +} + + +bool +set_dprintf_enabled(bool newState) +{ + bool oldState = sSerialDebugEnabled; + sSerialDebugEnabled = newState; + + return oldState; +} + + void dprintf(const char *fmt, ...) { va_list args; char temp[512]; - if (serial_debug_on) { + if (sSerialDebugEnabled) { va_start(args, fmt); vsprintf(temp, fmt, args); va_end(args); @@ -325,169 +494,21 @@ dprintf(const char *fmt, ...) } - -char -dbg_putch(char c) -{ - char ret; - cpu_status state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); - - if (serial_debug_on) - ret = arch_dbg_con_putch(c); - else - ret = c; - - release_spinlock(&dbg_spinlock); - restore_interrupts(state); - - return ret; -} +// #pragma mark - +// userland syscalls void -dbg_puts(const char *s) +_user_debug_output(const char *userString) { - cpu_status state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); + char string[1024]; - if (serial_debug_on) - arch_dbg_con_puts(s); + if (!sSerialDebugEnabled) + return; - release_spinlock(&dbg_spinlock); - restore_interrupts(state); + if (!CHECK_USER_ADDRESS(userString) + || user_strlcpy(string, userString, sizeof(string)) < B_OK) + return; + + dbg_puts(userString); } - - -int -add_debugger_command(char *name, int (*func)(int, char **), char *desc) -{ - cpu_status state; - struct debugger_command *cmd; - - cmd = (struct debugger_command *)malloc(sizeof(struct debugger_command)); - if (cmd == NULL) - return ENOMEM; - - cmd->func = func; - cmd->name = name; - cmd->description = desc; - - state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); - - cmd->next = commands; - commands = cmd; - - release_spinlock(&dbg_spinlock); - restore_interrupts(state); - - return B_NO_ERROR; -} - - -int -remove_debugger_command(char * name, int (*func)(int, char **)) -{ - struct debugger_command *cmd = commands; - struct debugger_command *prev = NULL; - cpu_status state; - - state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); - - while (cmd) { - if (!strcmp(cmd->name, name) && cmd->func == func) - break; - - prev = cmd; - cmd = cmd->next; - } - - if (cmd) { - if (cmd == commands) - commands = cmd->next; - else - prev->next = cmd->next; - } - - release_spinlock(&dbg_spinlock); - restore_interrupts(state); - - if (cmd) { - free(cmd); - return B_NO_ERROR; - } - - return B_NAME_NOT_FOUND; -} - - -static int -cmd_reboot(int argc, char **argv) -{ - reboot(); - return 0; // I'll be really suprised if this line ever run! ;-) -} - - -static int -cmd_help(int argc, char **argv) -{ - struct debugger_command *cmd; - - dprintf("debugger commands:\n"); - cmd = commands; - while (cmd != NULL) { - dprintf(" %-32s\t\t%s\n", cmd->name, cmd->description); - cmd = cmd->next; - } - - return 0; -} - - -int -dbg_init(kernel_args *ka) -{ - commands = NULL; - - return arch_dbg_con_init(ka); -} - - -int -dbg_init2(kernel_args *ka) -{ - add_debugger_command("help", &cmd_help, "List all debugger commands"); - add_debugger_command("reboot", &cmd_reboot, "Reboot"); - add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); - - return arch_dbg_init(ka); -} - - -bool -dbg_set_serial_debug(bool new_val) -{ - int temp = serial_debug_on; - serial_debug_on = new_val; - return temp; -} - - -bool -dbg_get_serial_debug() -{ - return serial_debug_on; -} - -// Wrapper(s) for BeOS R5 compatibility: - -bool -set_dprintf_enabled(bool new_state) -{ - return dbg_set_serial_debug(new_state); -} - - diff --git a/src/kernel/core/main.c b/src/kernel/core/main.c index ea90d39ee6..99268a4eb4 100644 --- a/src/kernel/core/main.c +++ b/src/kernel/core/main.c @@ -68,7 +68,7 @@ _start(kernel_args *oldka, int cpu_num) // setup debug output dbg_init(&ka); - dbg_set_serial_debug(true); + set_dprintf_enabled(true); dprintf("Welcome to kernel debugger output!\n"); // init modules