summary refs log tree commit diff stats
path: root/gdbstub/softmmu.c
diff options
context:
space:
mode:
authorMatheus Tavares Bernardino <quic_mathbern@quicinc.com>2023-05-04 12:37:31 -0300
committerTaylor Simpson <tsimpson@quicinc.com>2023-05-18 12:40:52 -0700
commit758370052fb602f9f23c3b8ae26a6133373c78e6 (patch)
tree6953d7d93c67618e73669f4b6102ebb99d10b6a4 /gdbstub/softmmu.c
parent9e6d4938d106ca775108ec2a1fecc6d789543088 (diff)
downloadfocaccia-qemu-758370052fb602f9f23c3b8ae26a6133373c78e6.tar.gz
focaccia-qemu-758370052fb602f9f23c3b8ae26a6133373c78e6.zip
gdbstub: only send stop-reply packets when allowed to
GDB's remote serial protocol allows stop-reply messages to be sent by
the stub either as a notification packet or as a reply to a GDB command
(provided that the cmd accepts such a response). QEMU currently does not
implement notification packets, so it should only send stop-replies
synchronously and when requested. Nevertheless, it still issues
unsolicited stop messages through gdb_vm_state_change().

Although this behavior doesn't seem to cause problems with GDB itself
(the messages are just ignored), it can impact other debuggers that
implement the GDB remote serial protocol, like hexagon-lldb. Let's
change the gdbstub to send stop messages only as a response to a
previous GDB command that accepts such a reply.

Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Message-Id: <a49c0897fc22a6a7827c8dfc32aef2e1d933ec6b.1683214375.git.quic_mathbern@quicinc.com>
Diffstat (limited to 'gdbstub/softmmu.c')
-rw-r--r--gdbstub/softmmu.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 22ecd09d04..99d994e6bf 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -43,6 +43,7 @@ static void reset_gdbserver_state(void)
     g_free(gdbserver_state.processes);
     gdbserver_state.processes = NULL;
     gdbserver_state.process_num = 0;
+    gdbserver_state.allow_stop_reply = false;
 }
 
 /*
@@ -139,6 +140,10 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
         return;
     }
 
+    if (!gdbserver_state.allow_stop_reply) {
+        return;
+    }
+
     gdb_append_thread_id(cpu, tid);
 
     switch (state) {
@@ -205,6 +210,7 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
 
 send_packet:
     gdb_put_packet(buf->str);
+    gdbserver_state.allow_stop_reply = false;
 
     /* disable single step if it was enabled */
     cpu_single_step(cpu, 0);
@@ -422,8 +428,11 @@ void gdb_exit(int code)
 
     trace_gdbstub_op_exiting((uint8_t)code);
 
-    snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
-    gdb_put_packet(buf);
+    if (gdbserver_state.allow_stop_reply) {
+        snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
+        gdb_put_packet(buf);
+        gdbserver_state.allow_stop_reply = false;
+    }
 
     qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
 }