In TCG there is a logic to wake up gdb client
after each TB executed if single-step mode enabled.
But when executing wfi we won't reach that logic,
cz long jump is performed. So after executing wfi
we do not wake up gdb client, and the next instruction is missed.

Furthermore, wfi sets `cpu->exception_index = EXCP_HLT`,
so we cannot set `cpu->exception_index = EXCP_DEBUG` as we usually do.

The desired behavior would be:
1. Perform wfi as is
2. Wait for hart to wake up (`cpu->halted = 0`)
3. Wake up gdb client

So let's modify `cpu_handle_exception()`. If we handle EXCP_HLT,
and single-step mode is enabled, instead of clearing `cpu->exception_index`
we schedule EXCP_DEBUG.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4794
Signed-off-by: Aleksandr Sergeev <[email protected]>
---
 accel/tcg/cpu-exec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 9ead35418d..08f9186b67 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -715,6 +715,16 @@ static inline bool cpu_handle_exception(CPUState *cpu, int 
*excp)
             cpu_handle_debug_exception(cpu);
         }
         cpu->exception_index = -1;
+
+        if (*excp == EXCP_HLT && unlikely(cpu_single_stepping(cpu))) {
+            /*
+             * After processing the halt, ensure an EXCP_DEBUG is
+             * raised when single-stepping so that GDB doesn't miss the
+             * next instruction.
+             */
+            cpu->exception_index = EXCP_DEBUG;
+        }
+
         return true;
     }
 
-- 
2.55.0


Reply via email to