gdbstub: Allow re-instantiation (Jan Kiszka)
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 28 Mar 2009 18:05:53 +0000 (18:05 +0000)
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 28 Mar 2009 18:05:53 +0000 (18:05 +0000)
[ 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

gdbstub.c
monitor.c

index 0860abd..518c939 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -265,6 +265,7 @@ typedef struct GDBRegisterState {
 } GDBRegisterState;
 
 enum RSState {
+    RS_INACTIVE,
     RS_IDLE,
     RS_GETLINE,
     RS_CHKSUM1,
@@ -1924,7 +1925,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
     int ret;
 
     if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
-        s->state == RS_SYSCALL)
+        s->state == RS_INACTIVE || s->state == RS_SYSCALL)
         return;
 
     /* disable single step if it was enable */
@@ -2342,36 +2343,50 @@ int gdbserver_start(const char *port)
     char gdbstub_port_name[128];
     int port_num;
     char *p;
-    CharDriverState *chr;
+    CharDriverState *chr = NULL;
+    CharDriverState *mon_chr;
 
     if (!port || !*port)
       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);
-    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;
+        chr = qemu_chr_open("gdb", port, NULL);
+        if (!chr)
+            return -1;
+
+        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
+                              gdb_chr_event, NULL);
     }
 
-    chr = qemu_chr_open("gdb", port, NULL);
-    if (!chr)
-        return -1;
+    s = gdbserver_state;
+    if (!s) {
+        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->g_cpu = first_cpu;
     s->chr = chr;
-    gdbserver_state = s;
-    qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
-                          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);
+    s->state = chr ? RS_IDLE : RS_INACTIVE;
+    s->mon_chr = mon_chr;
 
     return 0;
 }
index da106d8..c6fe968 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -577,6 +577,8 @@ static void do_gdbserver(Monitor *mon, const char *port)
     if (gdbserver_start(port) < 0) {
         monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n",
                        port);
+    } else if (strcmp(port, "none") == 0) {
+        monitor_printf(mon, "Disabled gdbserver\n");
     } else {
         monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port);
     }