* Added add_debugger_command_etc() which is similar to
add_debugger_command(), but additionally takes parameters "usage" and "flags". * Added add_debugger_command_alias() which creates another name for an existing command. * Added print_debugger_command_usage() to print a command's usage. * invoke_debugger_command() intercepts invocations with "--help" and prints the command's usage text, if it is known. If unknown, the command will be called normally. * Made use of the new functions in debug.cpp. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23573 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -70,6 +70,13 @@ extern bool evaluate_debug_expression(const char* expression,
|
|||||||
uint64* result, bool silent);
|
uint64* result, bool silent);
|
||||||
extern int evaluate_debug_command(const char* command);
|
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);
|
extern void _user_debug_output(const char *userString);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -204,9 +204,7 @@ public:
|
|||||||
|
|
||||||
if (command != NULL) {
|
if (command != NULL) {
|
||||||
kputchar('\n');
|
kputchar('\n');
|
||||||
|
print_debugger_command_usage(command->name);
|
||||||
char* args[3] = { NULL, "--help", NULL };
|
|
||||||
invoke_debugger_command(command, 2, args);
|
|
||||||
} else {
|
} else {
|
||||||
if (ambiguous)
|
if (ambiguous)
|
||||||
kprintf("\nambiguous command\n");
|
kprintf("\nambiguous command\n");
|
||||||
@@ -558,13 +556,6 @@ kernel_debugger_loop(void)
|
|||||||
static int
|
static int
|
||||||
cmd_reboot(int argc, char **argv)
|
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);
|
arch_cpu_shutdown(true);
|
||||||
return 0;
|
return 0;
|
||||||
// I'll be really suprised if this line ever runs! ;-)
|
// I'll be really suprised if this line ever runs! ;-)
|
||||||
@@ -574,13 +565,6 @@ cmd_reboot(int argc, char **argv)
|
|||||||
static int
|
static int
|
||||||
cmd_shutdown(int argc, char **argv)
|
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);
|
arch_cpu_shutdown(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -589,13 +573,6 @@ cmd_shutdown(int argc, char **argv)
|
|||||||
static int
|
static int
|
||||||
cmd_help(int argc, char **argv)
|
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;
|
debugger_command *command, *specified = NULL;
|
||||||
const char *start = NULL;
|
const char *start = NULL;
|
||||||
int32 startLength = 0;
|
int32 startLength = 0;
|
||||||
@@ -634,13 +611,6 @@ cmd_help(int argc, char **argv)
|
|||||||
static int
|
static int
|
||||||
cmd_continue(int argc, char **argv)
|
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;
|
return B_KDEBUG_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,13 +618,6 @@ cmd_continue(int argc, char **argv)
|
|||||||
static int
|
static int
|
||||||
cmd_dump_kdl_message(int argc, char **argv)
|
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) {
|
if (sCurrentKernelDebuggerMessage) {
|
||||||
kputs(sCurrentKernelDebuggerMessage);
|
kputs(sCurrentKernelDebuggerMessage);
|
||||||
kputchar('\n');
|
kputchar('\n');
|
||||||
@@ -666,10 +629,8 @@ cmd_dump_kdl_message(int argc, char **argv)
|
|||||||
static int
|
static int
|
||||||
cmd_expr(int argc, char **argv)
|
cmd_expr(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const char* usage = "usage: %s <expression>\n"
|
if (argc != 2) {
|
||||||
"Evaluates the given expression and prints the result.\n";
|
print_debugger_command_usage(argv[0]);
|
||||||
if (argc != 2 || strcmp(argv[1], "--help") == 0) {
|
|
||||||
kprintf(usage, argv[0]);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,19 +878,31 @@ debug_init(kernel_args *args)
|
|||||||
status_t
|
status_t
|
||||||
debug_init_post_vm(kernel_args *args)
|
debug_init_post_vm(kernel_args *args)
|
||||||
{
|
{
|
||||||
void *handle;
|
add_debugger_command_etc("help", &cmd_help, "List all debugger commands",
|
||||||
|
"usage: %s [name]\n"
|
||||||
add_debugger_command("help", &cmd_help, "List all debugger commands");
|
"Lists all debugger commands or those starting with \"name\".\n", 0);
|
||||||
add_debugger_command("reboot", &cmd_reboot, "Reboot the system");
|
add_debugger_command_etc("reboot", &cmd_reboot, "Reboot the system",
|
||||||
add_debugger_command("shutdown", &cmd_shutdown, "Shut down the system");
|
"usage: %s\n"
|
||||||
add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb");
|
"Reboots the system.\n", 0);
|
||||||
add_debugger_command("exit", &cmd_continue, "Same as \"continue\"");
|
add_debugger_command_etc("shutdown", &cmd_shutdown, "Shut down the system",
|
||||||
add_debugger_command("es", &cmd_continue, "Same as \"continue\"");
|
"usage: %s\n"
|
||||||
add_debugger_command("continue", &cmd_continue, "Leave kernel debugger");
|
"Shuts down the system.\n", 0);
|
||||||
add_debugger_command("message", &cmd_dump_kdl_message,
|
add_debugger_command_etc("gdb", &cmd_gdb, "Connect to remote gdb",
|
||||||
"Reprint the message printed when entering KDL");
|
"usage: %s\n"
|
||||||
add_debugger_command("expr", &cmd_expr,
|
"Connects to a remote gdb connected to the serial port.\n", 0);
|
||||||
"Evaluates the given expression and prints the result");
|
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 <expression>\n"
|
||||||
|
"Evaluates the given expression and prints the result.\n", 0);
|
||||||
|
|
||||||
debug_variables_init();
|
debug_variables_init();
|
||||||
frame_buffer_console_init(args);
|
frame_buffer_console_init(args);
|
||||||
@@ -937,7 +910,7 @@ debug_init_post_vm(kernel_args *args)
|
|||||||
tracing_init();
|
tracing_init();
|
||||||
|
|
||||||
// get debug settings
|
// get debug settings
|
||||||
handle = load_driver_settings("kernel");
|
void *handle = load_driver_settings("kernel");
|
||||||
if (handle != NULL) {
|
if (handle != NULL) {
|
||||||
sSerialDebugEnabled = get_driver_boolean_parameter(handle,
|
sSerialDebugEnabled = get_driver_boolean_parameter(handle,
|
||||||
"serial_debug_output", sSerialDebugEnabled, sSerialDebugEnabled);
|
"serial_debug_output", sSerialDebugEnabled, sSerialDebugEnabled);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include "debug_variables.h"
|
#include "debug_variables.h"
|
||||||
|
|
||||||
@@ -94,6 +95,14 @@ in_command_invocation(void)
|
|||||||
int
|
int
|
||||||
invoke_debugger_command(struct debugger_command *command, int argc, char** argv)
|
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();
|
struct thread* thread = thread_get_current_thread();
|
||||||
addr_t oldFaultHandler = thread->fault_handler;
|
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
|
// #pragma mark - public API
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
add_debugger_command(char *name, int (*func)(int, char **), char *desc)
|
add_debugger_command(char *name, int (*func)(int, char **), char *desc)
|
||||||
{
|
{
|
||||||
cpu_status state;
|
return add_debugger_command_etc(name, func, desc, NULL, 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
|
|
||||||
|
|
||||||
struct debugger_command {
|
struct debugger_command {
|
||||||
struct debugger_command *next;
|
struct debugger_command* next;
|
||||||
int (*func)(int, char **);
|
int (*func)(int, char **);
|
||||||
const char *name;
|
const char* name;
|
||||||
const char *description;
|
const char* description;
|
||||||
|
const char* usage;
|
||||||
|
uint32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Reference in New Issue
Block a user