]> git.proxmox.com Git - qemu.git/commitdiff
gdbstub: Catch and report more vmstop reasons
authorJan Kiszka <jan.kiszka@siemens.com>
Tue, 22 Mar 2011 10:02:09 +0000 (11:02 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Sun, 3 Apr 2011 21:57:39 +0000 (23:57 +0200)
When the VM goes into stop state while there is a gdb frontend attached,
it makes sense to inform gdb about this fact and at least a bit about
the stop reason. Basically, all stops are interesting except for the
temporary VMSTOP_SAVE/LOADVM.

The patch maps the relevant VMSTOP reasons on unique and more or less
associatable signals that gdb understands.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
gdbstub.c

index 1e9f9312dea51067242219b0493c2fa6614d2725..0838948c5cda3c12f8211dab4ef0348dbb5cc180 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
 enum {
     GDB_SIGNAL_0 = 0,
     GDB_SIGNAL_INT = 2,
+    GDB_SIGNAL_QUIT = 3,
     GDB_SIGNAL_TRAP = 5,
+    GDB_SIGNAL_ABRT = 6,
+    GDB_SIGNAL_ALRM = 14,
+    GDB_SIGNAL_IO = 23,
+    GDB_SIGNAL_XCPU = 24,
     GDB_SIGNAL_UNKNOWN = 143
 };
 
@@ -2270,14 +2275,11 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
     const char *type;
     int ret;
 
-    if (running || (reason != VMSTOP_DEBUG && reason != VMSTOP_USER) ||
-        s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
+    if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
         return;
     }
-    /* disable single step if it was enable */
-    cpu_single_step(env, 0);
-
-    if (reason == VMSTOP_DEBUG) {
+    switch (reason) {
+    case VMSTOP_DEBUG:
         if (env->watchpoint_hit) {
             switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
             case BP_MEM_READ:
@@ -2294,17 +2296,44 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
                      "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
                      GDB_SIGNAL_TRAP, gdb_id(env), type,
                      env->watchpoint_hit->vaddr);
-            put_packet(s, buf);
             env->watchpoint_hit = NULL;
-            return;
+            goto send_packet;
         }
-       tb_flush(env);
+        tb_flush(env);
         ret = GDB_SIGNAL_TRAP;
-    } else {
+        break;
+    case VMSTOP_USER:
         ret = GDB_SIGNAL_INT;
+        break;
+    case VMSTOP_SHUTDOWN:
+        ret = GDB_SIGNAL_QUIT;
+        break;
+    case VMSTOP_DISKFULL:
+        ret = GDB_SIGNAL_IO;
+        break;
+    case VMSTOP_WATCHDOG:
+        ret = GDB_SIGNAL_ALRM;
+        break;
+    case VMSTOP_PANIC:
+        ret = GDB_SIGNAL_ABRT;
+        break;
+    case VMSTOP_SAVEVM:
+    case VMSTOP_LOADVM:
+        return;
+    case VMSTOP_MIGRATE:
+        ret = GDB_SIGNAL_XCPU;
+        break;
+    default:
+        ret = GDB_SIGNAL_UNKNOWN;
+        break;
     }
     snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
+
+send_packet:
     put_packet(s, buf);
+
+    /* disable single step if it was enabled */
+    cpu_single_step(env, 0);
 }
 #endif