diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 27824b897a..020e2c8186 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -70,6 +70,13 @@ extern bool evaluate_debug_expression(const char* expression, uint64* result, bool silent); extern int evaluate_debug_command(const char* command); +extern status_t add_debugger_command_etc(const char* name, + debugger_command_hook func, const char* description, + const char* usage, uint32 flags); +extern status_t add_debugger_command_alias(const char* newName, + const char* oldName, const char* description); +extern bool print_debugger_command_usage(const char* command); + extern void _user_debug_output(const char *userString); #ifdef __cplusplus diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index e99f019dbd..5f58c0db3d 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -204,9 +204,7 @@ public: if (command != NULL) { kputchar('\n'); - - char* args[3] = { NULL, "--help", NULL }; - invoke_debugger_command(command, 2, args); + print_debugger_command_usage(command->name); } else { if (ambiguous) kprintf("\nambiguous command\n"); @@ -558,13 +556,6 @@ kernel_debugger_loop(void) static int cmd_reboot(int argc, char **argv) { - static const char* usage = "usage: %s\n" - "Reboots the system.\n"; - if (argc > 1 && strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); - return 0; - } - arch_cpu_shutdown(true); return 0; // I'll be really suprised if this line ever runs! ;-) @@ -574,13 +565,6 @@ cmd_reboot(int argc, char **argv) static int cmd_shutdown(int argc, char **argv) { - static const char* usage = "usage: %s\n" - "Shuts down the system.\n"; - if (argc > 1 && strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); - return 0; - } - arch_cpu_shutdown(false); return 0; } @@ -589,13 +573,6 @@ cmd_shutdown(int argc, char **argv) static int cmd_help(int argc, char **argv) { - static const char* usage = "usage: %s [name]\n" - "Lists all debugger commands or those starting with \"name\".\n"; - if (argc > 1 && strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); - return 0; - } - debugger_command *command, *specified = NULL; const char *start = NULL; int32 startLength = 0; @@ -634,13 +611,6 @@ cmd_help(int argc, char **argv) static int cmd_continue(int argc, char **argv) { - static const char* usage = "usage: %s\n" - "Leaves kernel debugger.\n"; - if (argc > 1 && strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); - return 0; - } - return B_KDEBUG_QUIT; } @@ -648,13 +618,6 @@ cmd_continue(int argc, char **argv) static int cmd_dump_kdl_message(int argc, char **argv) { - static const char* usage = "usage: %s\n" - "Reprints the message printed when entering KDL.\n"; - if (argc > 1 && strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); - return 0; - } - if (sCurrentKernelDebuggerMessage) { kputs(sCurrentKernelDebuggerMessage); kputchar('\n'); @@ -666,10 +629,8 @@ cmd_dump_kdl_message(int argc, char **argv) static int cmd_expr(int argc, char **argv) { - static const char* usage = "usage: %s \n" - "Evaluates the given expression and prints the result.\n"; - if (argc != 2 || strcmp(argv[1], "--help") == 0) { - kprintf(usage, argv[0]); + if (argc != 2) { + print_debugger_command_usage(argv[0]); return 0; } @@ -917,19 +878,31 @@ debug_init(kernel_args *args) status_t debug_init_post_vm(kernel_args *args) { - void *handle; - - add_debugger_command("help", &cmd_help, "List all debugger commands"); - add_debugger_command("reboot", &cmd_reboot, "Reboot the system"); - add_debugger_command("shutdown", &cmd_shutdown, "Shut down the system"); - add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); - add_debugger_command("exit", &cmd_continue, "Same as \"continue\""); - add_debugger_command("es", &cmd_continue, "Same as \"continue\""); - add_debugger_command("continue", &cmd_continue, "Leave kernel debugger"); - add_debugger_command("message", &cmd_dump_kdl_message, - "Reprint the message printed when entering KDL"); - add_debugger_command("expr", &cmd_expr, - "Evaluates the given expression and prints the result"); + add_debugger_command_etc("help", &cmd_help, "List all debugger commands", + "usage: %s [name]\n" + "Lists all debugger commands or those starting with \"name\".\n", 0); + add_debugger_command_etc("reboot", &cmd_reboot, "Reboot the system", + "usage: %s\n" + "Reboots the system.\n", 0); + add_debugger_command_etc("shutdown", &cmd_shutdown, "Shut down the system", + "usage: %s\n" + "Shuts down the system.\n", 0); + add_debugger_command_etc("gdb", &cmd_gdb, "Connect to remote gdb", + "usage: %s\n" + "Connects to a remote gdb connected to the serial port.\n", 0); + add_debugger_command_etc("continue", &cmd_continue, "Leave kernel debugger", + "usage: %s\n" + "Leaves kernel debugger.\n", 0); + add_debugger_command_alias("exit", "continue", "Same as \"continue\""); + add_debugger_command_alias("es", "continue", "Same as \"continue\""); + add_debugger_command_etc("message", &cmd_dump_kdl_message, + "Reprint the message printed when entering KDL", + "usage: %s\n" + "Reprints the message printed when entering KDL.\n", 0); + add_debugger_command_etc("expr", &cmd_expr, + "Evaluates the given expression and prints the result", + "usage: %s \n" + "Evaluates the given expression and prints the result.\n", 0); debug_variables_init(); frame_buffer_console_init(args); @@ -937,7 +910,7 @@ debug_init_post_vm(kernel_args *args) tracing_init(); // get debug settings - handle = load_driver_settings("kernel"); + void *handle = load_driver_settings("kernel"); if (handle != NULL) { sSerialDebugEnabled = get_driver_boolean_parameter(handle, "serial_debug_output", sSerialDebugEnabled, sSerialDebugEnabled); diff --git a/src/system/kernel/debug/debug_commands.cpp b/src/system/kernel/debug/debug_commands.cpp index 770b2d31d4..cf12b203cf 100644 --- a/src/system/kernel/debug/debug_commands.cpp +++ b/src/system/kernel/debug/debug_commands.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "debug_variables.h" @@ -94,6 +95,14 @@ in_command_invocation(void) int invoke_debugger_command(struct debugger_command *command, int argc, char** argv) { + // intercept invocations with "--help" and directly print the usage text + // If we know the command's usage text, intercept "--help" invocations + // and print it directly. + if (argc == 2 && strcmp(argv[1], "--help") == 0 && command->usage != NULL) { + kprintf(command->usage, command->name); + return 0; + } + struct thread* thread = thread_get_current_thread(); addr_t oldFaultHandler = thread->fault_handler; @@ -168,33 +177,79 @@ sort_debugger_commands() } +status_t +add_debugger_command_etc(const char* name, debugger_command_hook func, + const char* description, const char* usage, uint32 flags) +{ + struct debugger_command *cmd; + + cmd = (struct debugger_command*)malloc(sizeof(struct debugger_command)); + if (cmd == NULL) + return B_NO_MEMORY; + + cmd->func = func; + cmd->name = name; + cmd->description = description; + cmd->usage = usage; + cmd->flags = flags; + + InterruptsSpinLocker _(sSpinlock); + + cmd->next = sCommands; + sCommands = cmd; + + return B_OK; +} + + +status_t +add_debugger_command_alias(const char* newName, const char* oldName, + const char* description) +{ + // get the old command + bool ambiguous; + debugger_command* command = find_debugger_command(oldName, false, + ambiguous); + if (command == NULL) + return B_NAME_NOT_FOUND; + + // register new command + return add_debugger_command_etc(newName, command->func, + description != NULL ? description : command->description, + command->usage, command->flags); +} + + +bool +print_debugger_command_usage(const char* commandName) +{ + // get the command + bool ambiguous; + debugger_command* command = find_debugger_command(commandName, true, + ambiguous); + if (command == NULL) + return false; + + // directly print the usage text, if we know it, otherwise invoke the + // command with "--help" + if (command->usage != NULL) { + kprintf(command->usage, command->name); + } else { + char* args[3] = { NULL, "--help", NULL }; + invoke_debugger_command(command, 2, args); + } + + return true; +} + + // #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(&sSpinlock); - - cmd->next = sCommands; - sCommands = cmd; - - release_spinlock(&sSpinlock); - restore_interrupts(state); - - return B_NO_ERROR; + return add_debugger_command_etc(name, func, desc, NULL, 0); } diff --git a/src/system/kernel/debug/debug_commands.h b/src/system/kernel/debug/debug_commands.h index 0e519679b7..d7d8497f34 100644 --- a/src/system/kernel/debug/debug_commands.h +++ b/src/system/kernel/debug/debug_commands.h @@ -10,10 +10,12 @@ struct debugger_command { - struct debugger_command *next; - int (*func)(int, char **); - const char *name; - const char *description; + struct debugger_command* next; + int (*func)(int, char **); + const char* name; + const char* description; + const char* usage; + uint32 flags; }; #ifdef __cplusplus