Skip to content

Commit fc193b8

Browse files
committed
Fix issue with resolve_breakpoint failing during single step.
See [blog post](system.joekain.com/2025/07/30/multiple-breakpoints-redux.html for details of this fix. In summary, `resolve_breakpoint` doesn't work after the single step. So resolve the breakpoint up front and do the entire breakpoint single step and finish in one call to `breakpoint_handle`. Tests pass.
1 parent 173f3a2 commit fc193b8

1 file changed

Lines changed: 17 additions & 12 deletions

File tree

src/breakpoint.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include <trap.h>
22
#include "ptrace_util.h"
33
#include <assert.h>
4+
#include <signal.h>
45
#include <stdio.h>
56
#include <stdint.h>
67
#include <stdlib.h>
8+
#include <sys/wait.h>
79
#include <breakpoint.h>
810

911
enum breakpoint_state_t {
@@ -167,19 +169,22 @@ static void start_breakpoint(trap_inferior_t inferior,
167169

168170
enum inferior_state_t breakpoint_handle(trap_inferior_t inferior, enum inferior_state_t state)
169171
{
172+
pid_t pid = inferior;
170173
trap_breakpoint_t bp = breakpoint_resolve(inferior);
171-
172-
switch(state) {
173-
case INFERIOR_RUNNING:
174-
start_breakpoint(inferior, bp);
175-
return INFERIOR_SINGLE_STEPPING;
176-
177-
case INFERIOR_SINGLE_STEPPING:
178-
finish_breakpoint(inferior, bp);
179-
return INFERIOR_RUNNING;
180-
181-
default:
182-
abort();
174+
int status;
175+
176+
assert(state == INFERIOR_RUNNING);
177+
start_breakpoint(inferior, bp);
178+
waitpid(pid, &status, 0);
179+
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
180+
finish_breakpoint(inferior, bp);
181+
return INFERIOR_RUNNING;
182+
} else if (WIFEXITED(status)) {
183+
// This is a lie, but it should cause trap_inferior_continue to wait again.
184+
return INFERIOR_RUNNING;
185+
} else {
186+
fprintf(stderr, "Unexpected stop in trap_inferior_continue: 0x%x\n", status);
187+
abort();
183188
}
184189
}
185190

0 commit comments

Comments
 (0)