25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: debugger.c,v 1.21 2006/12/30 13:30:56 debug Exp $ |
* $Id: debugger.c,v 1.22 2007/03/26 02:01:36 debug Exp $ |
29 |
* |
* |
30 |
* Single-step debugger. |
* Single-step debugger. |
31 |
* |
* |
57 |
#include "cpu.h" |
#include "cpu.h" |
58 |
#include "device.h" |
#include "device.h" |
59 |
#include "debugger.h" |
#include "debugger.h" |
|
#include "debugger_gdb.h" |
|
60 |
#include "diskimage.h" |
#include "diskimage.h" |
61 |
#include "emul.h" |
#include "emul.h" |
62 |
#include "machine.h" |
#include "machine.h" |
126 |
*/ |
*/ |
127 |
char debugger_readchar(void) |
char debugger_readchar(void) |
128 |
{ |
{ |
129 |
int ch, i, j; |
int ch; |
130 |
|
|
131 |
while ((ch = console_readchar(MAIN_CONSOLE)) < 0 && !exit_debugger) { |
while ((ch = console_readchar(MAIN_CONSOLE)) < 0 && !exit_debugger) { |
132 |
/* Check for X11 events: */ |
/* Check for X11 events: */ |
133 |
x11_check_event(debugger_emuls, debugger_n_emuls); |
x11_check_event(debugger_emuls, debugger_n_emuls); |
134 |
|
|
|
/* Check for incoming GDB packets: */ |
|
|
for (i=0; i<debugger_n_emuls; i++) { |
|
|
struct emul *e = debugger_emuls[i]; |
|
|
if (e == NULL) |
|
|
continue; |
|
|
|
|
|
for (j=0; j<e->n_machines; j++) { |
|
|
if (e->machines[j]->gdb.port > 0) |
|
|
debugger_gdb_check_incoming( |
|
|
e->machines[j]); |
|
|
} |
|
|
} |
|
|
|
|
|
/* TODO: The X11 and GDB checks above should probably |
|
|
be factored out... */ |
|
|
|
|
135 |
/* Give up some CPU time: */ |
/* Give up some CPU time: */ |
136 |
usleep(10000); |
usleep(10000); |
137 |
} |
} |
656 |
debugger_machine->cpus[i], 0, INVALIDATE_ALL); |
debugger_machine->cpus[i], 0, INVALIDATE_ALL); |
657 |
} |
} |
658 |
|
|
|
/* |
|
|
* Ugly GDB hack: After single stepping, we need to send back |
|
|
* status to GDB: |
|
|
*/ |
|
|
if (exit_debugger == -1) { |
|
|
int i, j; |
|
|
for (i=0; i<debugger_n_emuls; i++) { |
|
|
struct emul *e = debugger_emuls[i]; |
|
|
if (e == NULL) |
|
|
continue; |
|
|
|
|
|
for (j=0; j<e->n_machines; j++) { |
|
|
if (e->machines[j]->gdb.port > 0) |
|
|
debugger_gdb_after_singlestep( |
|
|
e->machines[j]); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
659 |
/* Stop timers while interacting with the user: */ |
/* Stop timers while interacting with the user: */ |
660 |
timer_stop(); |
timer_stop(); |
661 |
|
|
665 |
/* Read a line from the terminal: */ |
/* Read a line from the terminal: */ |
666 |
cmd = debugger_readline(); |
cmd = debugger_readline(); |
667 |
|
|
|
/* Special hack for the "step" _GDB_ command: */ |
|
|
if (exit_debugger == -1) |
|
|
return; |
|
|
|
|
668 |
cmd_len = strlen(cmd); |
cmd_len = strlen(cmd); |
669 |
|
|
670 |
/* Remove spaces: */ |
/* Remove spaces: */ |
731 |
*/ |
*/ |
732 |
void debugger_init(struct emul **emuls, int n_emuls) |
void debugger_init(struct emul **emuls, int n_emuls) |
733 |
{ |
{ |
734 |
int i, j; |
int i; |
735 |
|
|
736 |
debugger_n_emuls = n_emuls; |
debugger_n_emuls = n_emuls; |
737 |
debugger_emuls = emuls; |
debugger_emuls = emuls; |
748 |
exit(1); |
exit(1); |
749 |
} |
} |
750 |
|
|
|
for (i=0; i<n_emuls; i++) |
|
|
for (j=0; j<emuls[i]->n_machines; j++) |
|
|
debugger_gdb_init(emuls[i]->machines[j]); |
|
|
|
|
751 |
debugger_machine = emuls[0]->machines[0]; |
debugger_machine = emuls[0]->machines[0]; |
752 |
|
|
753 |
debugger_cur_cpu = 0; |
debugger_cur_cpu = 0; |