gdbstub: Allow re-instantiation (Jan Kiszka)
[ Note: depends on char closing fixes ] Properly clean up the gdbstub when the user tries to re-open it (possibly under a different address). Moreover, allow to shut it down from the monitor via 'gdbserver none'. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6913 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
819f56b7fb
commit
36556b20c5
57
gdbstub.c
57
gdbstub.c
@ -265,6 +265,7 @@ typedef struct GDBRegisterState {
|
|||||||
} GDBRegisterState;
|
} GDBRegisterState;
|
||||||
|
|
||||||
enum RSState {
|
enum RSState {
|
||||||
|
RS_INACTIVE,
|
||||||
RS_IDLE,
|
RS_IDLE,
|
||||||
RS_GETLINE,
|
RS_GETLINE,
|
||||||
RS_CHKSUM1,
|
RS_CHKSUM1,
|
||||||
@ -1924,7 +1925,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
|
if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
|
||||||
s->state == RS_SYSCALL)
|
s->state == RS_INACTIVE || s->state == RS_SYSCALL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* disable single step if it was enable */
|
/* disable single step if it was enable */
|
||||||
@ -2342,36 +2343,50 @@ int gdbserver_start(const char *port)
|
|||||||
char gdbstub_port_name[128];
|
char gdbstub_port_name[128];
|
||||||
int port_num;
|
int port_num;
|
||||||
char *p;
|
char *p;
|
||||||
CharDriverState *chr;
|
CharDriverState *chr = NULL;
|
||||||
|
CharDriverState *mon_chr;
|
||||||
|
|
||||||
if (!port || !*port)
|
if (!port || !*port)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (strcmp(port, "none") != 0) {
|
||||||
|
port_num = strtol(port, &p, 10);
|
||||||
|
if (*p == 0) {
|
||||||
|
/* A numeric value is interpreted as a port number. */
|
||||||
|
snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
|
||||||
|
"tcp::%d,nowait,nodelay,server", port_num);
|
||||||
|
port = gdbstub_port_name;
|
||||||
|
}
|
||||||
|
|
||||||
port_num = strtol(port, &p, 10);
|
chr = qemu_chr_open("gdb", port, NULL);
|
||||||
if (*p == 0) {
|
if (!chr)
|
||||||
/* A numeric value is interpreted as a port number. */
|
return -1;
|
||||||
snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
|
|
||||||
"tcp::%d,nowait,nodelay,server", port_num);
|
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
|
||||||
port = gdbstub_port_name;
|
gdb_chr_event, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
chr = qemu_chr_open("gdb", port, NULL);
|
s = gdbserver_state;
|
||||||
if (!chr)
|
if (!s) {
|
||||||
return -1;
|
s = qemu_mallocz(sizeof(GDBState));
|
||||||
|
gdbserver_state = s;
|
||||||
|
|
||||||
s = qemu_mallocz(sizeof(GDBState));
|
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
|
||||||
|
|
||||||
|
/* Initialize a monitor terminal for gdb */
|
||||||
|
mon_chr = qemu_mallocz(sizeof(*mon_chr));
|
||||||
|
mon_chr->chr_write = gdb_monitor_write;
|
||||||
|
monitor_init(mon_chr, 0);
|
||||||
|
} else {
|
||||||
|
if (s->chr)
|
||||||
|
qemu_chr_close(s->chr);
|
||||||
|
mon_chr = s->mon_chr;
|
||||||
|
memset(s, 0, sizeof(GDBState));
|
||||||
|
}
|
||||||
s->c_cpu = first_cpu;
|
s->c_cpu = first_cpu;
|
||||||
s->g_cpu = first_cpu;
|
s->g_cpu = first_cpu;
|
||||||
s->chr = chr;
|
s->chr = chr;
|
||||||
gdbserver_state = s;
|
s->state = chr ? RS_IDLE : RS_INACTIVE;
|
||||||
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
|
s->mon_chr = mon_chr;
|
||||||
gdb_chr_event, NULL);
|
|
||||||
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
|
|
||||||
|
|
||||||
/* Initialize a monitor terminal for gdb */
|
|
||||||
s->mon_chr = qemu_mallocz(sizeof(*s->mon_chr));
|
|
||||||
s->mon_chr->chr_write = gdb_monitor_write;
|
|
||||||
monitor_init(s->mon_chr, 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -577,6 +577,8 @@ static void do_gdbserver(Monitor *mon, const char *port)
|
|||||||
if (gdbserver_start(port) < 0) {
|
if (gdbserver_start(port) < 0) {
|
||||||
monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n",
|
monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n",
|
||||||
port);
|
port);
|
||||||
|
} else if (strcmp(port, "none") == 0) {
|
||||||
|
monitor_printf(mon, "Disabled gdbserver\n");
|
||||||
} else {
|
} else {
|
||||||
monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port);
|
monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user