Skip to contentSkip to conversation

GDB serial protocol fixes (detach, kill, and initial status query)

PATCH New Jason Wessel 1 participant 1 message Jul 31, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 GDB serial protocol fixes (detach, kill, and initial status query)

I have occasionally found that I have killed off gdb, and had no way to recover a debug session to QEMU. Also the detach/kill sequence does not work correctly protocol wise in the QEMU gdb-stub. This patch addresses these problems.

I implemented the serial protocol commands the same way as in KGDB.

? = Query state, but also clear the breakpoints.
- KGDB/gdb do the same thing so that in case you lose your session or context, gdb always send the "?" command during the connect sequence. This ensures that gdb has a clean slate for breakpoints and run control.

D = Detach and clear all breakpoints with return "OK"

k = Do the same thing as D for now
In the future this can be used to kill the target emulation. But for now it makes gdb and other gdb serial debugger happy.

Signed-off-by [email protected]

Thanks,
Jason.

cpu-all.h +1 -0
Index: qemu/cpu-all.h
===================================================================
@@ -768,6 +768,7 @@ void cpu_reset_interrupt(CPUState *env, 
 
 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
 int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
+int cpu_breakpoint_remove_all(CPUState *env);
 void cpu_single_step(CPUState *env, int enabled);
 void cpu_reset(CPUState *s);
 
gdbstub.c +14 -0
Index: qemu/gdbstub.c
===================================================================
@@ -580,6 +580,8 @@ static int gdb_handle_packet(GDBState *s
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
         put_packet(s, buf);
+        /* Remove all the breakpoints when this query is issued. */
+        cpu_breakpoint_remove_all(env);
         break;
     case 'c':
         if (*p != '\0') {
@@ -603,6 +605,18 @@ static int gdb_handle_packet(GDBState *s
         vm_start();
 #endif
 	return RS_IDLE;
+    case 'k':
+    case 'D':
+        /* Detach packet */
+        if (!cpu_breakpoint_remove_all(env)) {
+#ifdef CONFIG_USER_ONLY
+            s->running_state = 1;
+#else
+            vm_start();
+#endif
+            put_packet(s, "OK");
+            break;
+        }
     case 's':
         if (*p != '\0') {
             addr = strtoul(p, (char **)&p, 16);