The kernel debugger no longer uses dprintf() but kprintf() when printing
(dprintf() locks using acquire_spinlock() which can itself drop into the kernel debugger, causing an endless loop (until the stack was full). Removed debug_putchar(). The gdb interface is now calling arch_debug_serial_*() directly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13882 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,7 +31,6 @@ extern "C" {
|
|||||||
extern status_t debug_init(struct kernel_args *args);
|
extern status_t debug_init(struct kernel_args *args);
|
||||||
extern status_t debug_init_post_vm(struct kernel_args *args);
|
extern status_t debug_init_post_vm(struct kernel_args *args);
|
||||||
extern void debug_early_boot_message(const char *string);
|
extern void debug_early_boot_message(const char *string);
|
||||||
extern void debug_putchar(char c);
|
|
||||||
extern void debug_puts(const char *s);
|
extern void debug_puts(const char *s);
|
||||||
|
|
||||||
extern void _user_debug_output(const char *userString);
|
extern void _user_debug_output(const char *userString);
|
||||||
|
|||||||
@@ -90,11 +90,31 @@ find_command(char *name, bool partialMatch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
kputchar(char c)
|
||||||
|
{
|
||||||
|
if (sSerialDebugEnabled)
|
||||||
|
arch_debug_serial_putchar(c);
|
||||||
|
if (sBlueScreenOutput)
|
||||||
|
blue_screen_putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
kputs(const char *s)
|
||||||
|
{
|
||||||
|
if (sSerialDebugEnabled)
|
||||||
|
arch_debug_serial_puts(s);
|
||||||
|
if (sBlueScreenOutput)
|
||||||
|
blue_screen_puts(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_line(char *buf, int max_len)
|
read_line(char *buf, int max_len)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
int ptr = 0;
|
int position = 0;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
int cur_history_spot = cur_line;
|
int cur_history_spot = cur_line;
|
||||||
|
|
||||||
@@ -110,16 +130,16 @@ read_line(char *buf, int max_len)
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
buf[ptr++] = '\0';
|
buf[position++] = '\0';
|
||||||
debug_putchar('\n');
|
kputchar('\n');
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
case 8: // backspace
|
case 8: // backspace
|
||||||
if (ptr > 0) {
|
if (position > 0) {
|
||||||
debug_puts("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
debug_putchar(' ');
|
kputchar(' ');
|
||||||
debug_puts("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
ptr--;
|
position--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 27: // escape sequence
|
case 27: // escape sequence
|
||||||
@@ -127,15 +147,15 @@ read_line(char *buf, int max_len)
|
|||||||
c = readChar();
|
c = readChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 67: // right arrow acts like space
|
case 67: // right arrow acts like space
|
||||||
buf[ptr++] = ' ';
|
buf[position++] = ' ';
|
||||||
debug_putchar(' ');
|
kputchar(' ');
|
||||||
break;
|
break;
|
||||||
case 68: // left arrow acts like backspace
|
case 68: // left arrow acts like backspace
|
||||||
if (ptr > 0) {
|
if (position > 0) {
|
||||||
debug_puts("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
debug_putchar(' ');
|
kputchar(' ');
|
||||||
debug_puts("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
ptr--;
|
position--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 65: // up arrow
|
case 65: // up arrow
|
||||||
@@ -154,7 +174,7 @@ read_line(char *buf, int max_len)
|
|||||||
// down arrow
|
// down arrow
|
||||||
if (cur_history_spot != cur_line) {
|
if (cur_history_spot != cur_line) {
|
||||||
history_line = cur_history_spot + 1;
|
history_line = cur_history_spot + 1;
|
||||||
if(history_line >= HISTORY_SIZE)
|
if (history_line >= HISTORY_SIZE)
|
||||||
history_line = 0;
|
history_line = 0;
|
||||||
} else
|
} else
|
||||||
break; // nothing to do here
|
break; // nothing to do here
|
||||||
@@ -163,12 +183,12 @@ read_line(char *buf, int max_len)
|
|||||||
// dprintf("2c %d h %d ch %d\n", cur_line, history_line, cur_history_spot);
|
// dprintf("2c %d h %d ch %d\n", cur_line, history_line, cur_history_spot);
|
||||||
|
|
||||||
// swap the current line with something from the history
|
// swap the current line with something from the history
|
||||||
if (ptr > 0)
|
if (position > 0)
|
||||||
dprintf("\x1b[%dD", ptr); // move to beginning of line
|
kprintf("\x1b[%dD", position); // move to beginning of line
|
||||||
|
|
||||||
strcpy(buf, line_buf[history_line]);
|
strcpy(buf, line_buf[history_line]);
|
||||||
ptr = strlen(buf);
|
position = strlen(buf);
|
||||||
dprintf("%s\x1b[K", buf); // print the line and clear the rest
|
kprintf("%s\x1b[K", buf); // print the line and clear the rest
|
||||||
cur_history_spot = history_line;
|
cur_history_spot = history_line;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -184,26 +204,27 @@ read_line(char *buf, int max_len)
|
|||||||
* If we get a $ at the beginning of the line
|
* If we get a $ at the beginning of the line
|
||||||
* we assume we are talking with GDB
|
* we assume we are talking with GDB
|
||||||
*/
|
*/
|
||||||
if (ptr == 0) {
|
if (position == 0) {
|
||||||
strcpy(buf, "gdb");
|
strcpy(buf, "gdb");
|
||||||
ptr = 4;
|
position = 4;
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* supposed to fall through */
|
/* supposed to fall through */
|
||||||
default:
|
default:
|
||||||
buf[ptr++] = c;
|
buf[position++] = c;
|
||||||
debug_putchar(c);
|
kputchar(c);
|
||||||
}
|
}
|
||||||
if (ptr >= max_len - 2) {
|
if (position >= max_len - 2) {
|
||||||
buf[ptr++] = '\0';
|
buf[position++] = '\0';
|
||||||
debug_puts("\n");
|
kputchar('\n');
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ptr;
|
|
||||||
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -253,7 +274,7 @@ kernel_debugger_loop(void)
|
|||||||
struct debugger_command *cmd = NULL;
|
struct debugger_command *cmd = NULL;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
dprintf("kdebug> ");
|
kprintf("kdebug> ");
|
||||||
read_line(line_buf[cur_line], LINE_BUF_SIZE);
|
read_line(line_buf[cur_line], LINE_BUF_SIZE);
|
||||||
parse_line(line_buf[cur_line], args, &argc, MAX_ARGS);
|
parse_line(line_buf[cur_line], args, &argc, MAX_ARGS);
|
||||||
|
|
||||||
@@ -268,7 +289,7 @@ kernel_debugger_loop(void)
|
|||||||
cmd = find_command(args[0], true);
|
cmd = find_command(args[0], true);
|
||||||
|
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
dprintf("unknown command, enter \"help\" to get a list of all supported commands\n");
|
kprintf("unknown command, enter \"help\" to get a list of all supported commands\n");
|
||||||
else {
|
else {
|
||||||
int rc = cmd->func(argc, args);
|
int rc = cmd->func(argc, args);
|
||||||
|
|
||||||
@@ -312,11 +333,11 @@ cmd_help(int argc, char **argv)
|
|||||||
|
|
||||||
if (specified != NULL) {
|
if (specified != NULL) {
|
||||||
// only print out the help of the specified command (and all of its aliases)
|
// only print out the help of the specified command (and all of its aliases)
|
||||||
dprintf("debugger command for \"%s\" and aliases:\n", specified->name);
|
kprintf("debugger command for \"%s\" and aliases:\n", specified->name);
|
||||||
} else if (start != NULL)
|
} else if (start != NULL)
|
||||||
dprintf("debugger commands starting with \"%s\":\n", start);
|
kprintf("debugger commands starting with \"%s\":\n", start);
|
||||||
else
|
else
|
||||||
dprintf("debugger commands:\n");
|
kprintf("debugger commands:\n");
|
||||||
|
|
||||||
for (command = sCommands; command != NULL; command = command->next) {
|
for (command = sCommands; command != NULL; command = command->next) {
|
||||||
if (specified && command->func != specified->func)
|
if (specified && command->func != specified->func)
|
||||||
@@ -324,7 +345,7 @@ cmd_help(int argc, char **argv)
|
|||||||
if (start != NULL && strncmp(start, command->name, startLength))
|
if (start != NULL && strncmp(start, command->name, startLength))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dprintf(" %-20s\t\t%s\n", command->name, command->description ? command->description : "-");
|
kprintf(" %-20s\t\t%s\n", command->name, command->description ? command->description : "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -338,35 +359,16 @@ cmd_continue(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - private kernel API
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_putchar(char c)
|
debug_puts(const char *string)
|
||||||
{
|
{
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
acquire_spinlock(&sSpinlock);
|
acquire_spinlock(&sSpinlock);
|
||||||
|
|
||||||
if (sSerialDebugEnabled)
|
kputs(string);
|
||||||
arch_debug_serial_putchar(c);
|
|
||||||
if (sBlueScreenOutput)
|
|
||||||
blue_screen_putchar(c);
|
|
||||||
|
|
||||||
release_spinlock(&sSpinlock);
|
|
||||||
restore_interrupts(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
debug_puts(const char *s)
|
|
||||||
{
|
|
||||||
cpu_status state = disable_interrupts();
|
|
||||||
acquire_spinlock(&sSpinlock);
|
|
||||||
|
|
||||||
if (sSerialDebugEnabled)
|
|
||||||
arch_debug_serial_puts(s);
|
|
||||||
if (sBlueScreenOutput)
|
|
||||||
blue_screen_puts(s);
|
|
||||||
|
|
||||||
release_spinlock(&sSpinlock);
|
release_spinlock(&sSpinlock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
@@ -421,8 +423,7 @@ debug_init_post_vm(kernel_args *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - public API
|
||||||
// public API
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -593,7 +594,7 @@ dprintf(const char *format, ...)
|
|||||||
|
|
||||||
|
|
||||||
/** Similar to dprintf() but thought to be used in the kernel
|
/** Similar to dprintf() but thought to be used in the kernel
|
||||||
* debugger only.
|
* debugger only (it doesn't lock).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -607,7 +608,8 @@ kprintf(const char *format, ...)
|
|||||||
vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
|
vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
arch_debug_serial_puts(sOutputBuffer);
|
if (sSerialDebugEnabled)
|
||||||
|
arch_debug_serial_puts(sOutputBuffer);
|
||||||
if (sBlueScreenOutput)
|
if (sBlueScreenOutput)
|
||||||
blue_screen_puts(sOutputBuffer);
|
blue_screen_puts(sOutputBuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,21 +57,21 @@ parse_nibble(int input)
|
|||||||
static void
|
static void
|
||||||
gdb_ack(void)
|
gdb_ack(void)
|
||||||
{
|
{
|
||||||
debug_putchar('+');
|
arch_debug_serial_putchar('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdb_nak(void)
|
gdb_nak(void)
|
||||||
{
|
{
|
||||||
debug_putchar('-');
|
arch_debug_serial_putchar('-');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdb_resend_reply(void)
|
gdb_resend_reply(void)
|
||||||
{
|
{
|
||||||
debug_puts(reply);
|
arch_debug_serial_puts(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user