* Updated to use add_debugger_command_etc().
* Added "step" debugger command to single-step to the next instruction (of the topmost iframe). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30212 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -372,38 +372,24 @@ debugger_breakpoints(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
debugger_breakpoint_usage(const char* command)
|
|
||||||
{
|
|
||||||
if (command[0] == 'b') {
|
|
||||||
kprintf("Usage: breakpoint <address>\n");
|
|
||||||
kprintf(" breakpoint <address> clear\n");
|
|
||||||
} else {
|
|
||||||
kprintf("Usage: watchpoint <address> [ rw ] [ <size> ]\n");
|
|
||||||
kprintf(" watchpoint <address> clear\n");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
debugger_breakpoint(int argc, char** argv)
|
debugger_breakpoint(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// get arguments
|
// get arguments
|
||||||
|
|
||||||
if (argc < 2 || argc > 3)
|
if (argc < 2 || argc > 3)
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
|
|
||||||
addr_t address = strtoul(argv[1], NULL, 0);
|
addr_t address = strtoul(argv[1], NULL, 0);
|
||||||
if (address == 0)
|
if (address == 0)
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
|
|
||||||
bool clear = false;
|
bool clear = false;
|
||||||
if (argc == 3) {
|
if (argc == 3) {
|
||||||
if (strcmp(argv[2], "clear") == 0)
|
if (strcmp(argv[2], "clear") == 0)
|
||||||
clear = true;
|
clear = true;
|
||||||
else
|
else
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set/clear breakpoint
|
// set/clear breakpoint
|
||||||
@@ -434,11 +420,11 @@ debugger_watchpoint(int argc, char** argv)
|
|||||||
// get arguments
|
// get arguments
|
||||||
|
|
||||||
if (argc < 2 || argc > 4)
|
if (argc < 2 || argc > 4)
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
|
|
||||||
addr_t address = strtoul(argv[1], NULL, 0);
|
addr_t address = strtoul(argv[1], NULL, 0);
|
||||||
if (address == 0)
|
if (address == 0)
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
|
|
||||||
bool clear = false;
|
bool clear = false;
|
||||||
bool readWrite = false;
|
bool readWrite = false;
|
||||||
@@ -457,7 +443,7 @@ debugger_watchpoint(int argc, char** argv)
|
|||||||
length = strtoul(argv[argi++], NULL, 0);
|
length = strtoul(argv[argi++], NULL, 0);
|
||||||
|
|
||||||
if (length == 0 || argi < argc)
|
if (length == 0 || argi < argc)
|
||||||
return debugger_breakpoint_usage(argv[0]);
|
return print_debugger_command_usage(argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set/clear breakpoint
|
// set/clear breakpoint
|
||||||
@@ -490,6 +476,25 @@ debugger_watchpoint(int argc, char** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
debugger_single_step(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// TODO: Since we need an iframe, this doesn't work when KDL wasn't entered
|
||||||
|
// via an exception.
|
||||||
|
|
||||||
|
struct iframe* frame = i386_get_current_iframe();
|
||||||
|
if (frame == NULL) {
|
||||||
|
kprintf("Failed to get the current iframe!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->flags |= (1 << X86_EFLAGS_TF);
|
||||||
|
|
||||||
|
return B_KDEBUG_QUIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // KERNEL_BREAKPOINTS
|
#endif // KERNEL_BREAKPOINTS
|
||||||
|
|
||||||
|
|
||||||
@@ -839,8 +844,13 @@ x86_handle_debug_exception(struct iframe *frame)
|
|||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
user_debug_single_stepped();
|
user_debug_single_stepped();
|
||||||
} else
|
} else {
|
||||||
|
// Disable single-stepping -- the next "step" command will re-enable
|
||||||
|
// it, but we don't want it when continuing otherwise.
|
||||||
|
frame->flags &= ~(1 << X86_EFLAGS_TF);
|
||||||
|
|
||||||
panic("kernel single step");
|
panic("kernel single step");
|
||||||
|
}
|
||||||
} else if (dr6 & (1 << X86_DR6_BT)) {
|
} else if (dr6 & (1 << X86_DR6_BT)) {
|
||||||
// task switch
|
// task switch
|
||||||
// Occurs only, if T in EFLAGS is set (which we don't do).
|
// Occurs only, if T in EFLAGS is set (which we don't do).
|
||||||
@@ -897,14 +907,25 @@ x86_init_user_debug()
|
|||||||
|
|
||||||
#if KERNEL_BREAKPOINTS
|
#if KERNEL_BREAKPOINTS
|
||||||
// install debugger commands
|
// install debugger commands
|
||||||
add_debugger_command("breakpoints", &debugger_breakpoints,
|
add_debugger_command_etc("breakpoints", &debugger_breakpoints,
|
||||||
"lists current break-/watchpoints");
|
"Lists current break-/watchpoints",
|
||||||
add_debugger_command("breakpoint", &debugger_breakpoint,
|
"\n"
|
||||||
"set/clear a breakpoint");
|
"Lists the current kernel break-/watchpoints.\n", 0);
|
||||||
add_debugger_command("watchpoints", &debugger_breakpoints,
|
add_debugger_command_alias("watchpoints", "breakpoints", NULL);
|
||||||
"lists current break-/watchpoints");
|
add_debugger_command_etc("breakpoint", &debugger_breakpoint,
|
||||||
add_debugger_command("watchpoint", &debugger_watchpoint,
|
"Set/clears a breakpoint",
|
||||||
"set/clear a watchpoint");
|
"<address> [ clear ]\n"
|
||||||
|
"Sets respectively clears the breakpoint at address <address>.\n", 0);
|
||||||
|
add_debugger_command_etc("watchpoint", &debugger_watchpoint,
|
||||||
|
"Set/clears a watchpoint",
|
||||||
|
"<address> <address> ( [ rw ] [ <size> ] | clear )\n"
|
||||||
|
"Sets respectively clears the watchpoint at address <address>.\n"
|
||||||
|
"If \"rw\" is given the new watchpoint is a read/write watchpoint\n"
|
||||||
|
"otherwise a write watchpoint only.\n", 0);
|
||||||
|
add_debugger_command_etc("step", &debugger_single_step,
|
||||||
|
"Single-steps to the next instruction",
|
||||||
|
"\n"
|
||||||
|
"Single-steps to the next instruction.\n", 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user