Commit 36556b20c5c9a02f5e238435cd41bf67740359ee

Authored by aliguori
1 parent 819f56b7

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
Showing 2 changed files with 38 additions and 21 deletions
gdbstub.c
@@ -265,6 +265,7 @@ typedef struct GDBRegisterState { @@ -265,6 +265,7 @@ typedef struct GDBRegisterState {
265 } GDBRegisterState; 265 } GDBRegisterState;
266 266
267 enum RSState { 267 enum RSState {
  268 + RS_INACTIVE,
268 RS_IDLE, 269 RS_IDLE,
269 RS_GETLINE, 270 RS_GETLINE,
270 RS_CHKSUM1, 271 RS_CHKSUM1,
@@ -1924,7 +1925,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason) @@ -1924,7 +1925,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
1924 int ret; 1925 int ret;
1925 1926
1926 if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) || 1927 if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
1927 - s->state == RS_SYSCALL) 1928 + s->state == RS_INACTIVE || s->state == RS_SYSCALL)
1928 return; 1929 return;
1929 1930
1930 /* disable single step if it was enable */ 1931 /* disable single step if it was enable */
@@ -2342,36 +2343,50 @@ int gdbserver_start(const char *port) @@ -2342,36 +2343,50 @@ int gdbserver_start(const char *port)
2342 char gdbstub_port_name[128]; 2343 char gdbstub_port_name[128];
2343 int port_num; 2344 int port_num;
2344 char *p; 2345 char *p;
2345 - CharDriverState *chr; 2346 + CharDriverState *chr = NULL;
  2347 + CharDriverState *mon_chr;
2346 2348
2347 if (!port || !*port) 2349 if (!port || !*port)
2348 return -1; 2350 return -1;
  2351 + if (strcmp(port, "none") != 0) {
  2352 + port_num = strtol(port, &p, 10);
  2353 + if (*p == 0) {
  2354 + /* A numeric value is interpreted as a port number. */
  2355 + snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
  2356 + "tcp::%d,nowait,nodelay,server", port_num);
  2357 + port = gdbstub_port_name;
  2358 + }
2349 2359
2350 - port_num = strtol(port, &p, 10);  
2351 - if (*p == 0) {  
2352 - /* A numeric value is interpreted as a port number. */  
2353 - snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),  
2354 - "tcp::%d,nowait,nodelay,server", port_num);  
2355 - port = gdbstub_port_name; 2360 + chr = qemu_chr_open("gdb", port, NULL);
  2361 + if (!chr)
  2362 + return -1;
  2363 +
  2364 + qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
  2365 + gdb_chr_event, NULL);
2356 } 2366 }
2357 2367
2358 - chr = qemu_chr_open("gdb", port, NULL);  
2359 - if (!chr)  
2360 - return -1; 2368 + s = gdbserver_state;
  2369 + if (!s) {
  2370 + s = qemu_mallocz(sizeof(GDBState));
  2371 + gdbserver_state = s;
2361 2372
2362 - s = qemu_mallocz(sizeof(GDBState)); 2373 + qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
  2374 +
  2375 + /* Initialize a monitor terminal for gdb */
  2376 + mon_chr = qemu_mallocz(sizeof(*mon_chr));
  2377 + mon_chr->chr_write = gdb_monitor_write;
  2378 + monitor_init(mon_chr, 0);
  2379 + } else {
  2380 + if (s->chr)
  2381 + qemu_chr_close(s->chr);
  2382 + mon_chr = s->mon_chr;
  2383 + memset(s, 0, sizeof(GDBState));
  2384 + }
2363 s->c_cpu = first_cpu; 2385 s->c_cpu = first_cpu;
2364 s->g_cpu = first_cpu; 2386 s->g_cpu = first_cpu;
2365 s->chr = chr; 2387 s->chr = chr;
2366 - gdbserver_state = s;  
2367 - qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,  
2368 - gdb_chr_event, NULL);  
2369 - qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);  
2370 -  
2371 - /* Initialize a monitor terminal for gdb */  
2372 - s->mon_chr = qemu_mallocz(sizeof(*s->mon_chr));  
2373 - s->mon_chr->chr_write = gdb_monitor_write;  
2374 - monitor_init(s->mon_chr, 0); 2388 + s->state = chr ? RS_IDLE : RS_INACTIVE;
  2389 + s->mon_chr = mon_chr;
2375 2390
2376 return 0; 2391 return 0;
2377 } 2392 }
monitor.c
@@ -577,6 +577,8 @@ static void do_gdbserver(Monitor *mon, const char *port) @@ -577,6 +577,8 @@ static void do_gdbserver(Monitor *mon, const char *port)
577 if (gdbserver_start(port) < 0) { 577 if (gdbserver_start(port) < 0) {
578 monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n", 578 monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n",
579 port); 579 port);
  580 + } else if (strcmp(port, "none") == 0) {
  581 + monitor_printf(mon, "Disabled gdbserver\n");
580 } else { 582 } else {
581 monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port); 583 monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port);
582 } 584 }