summaryrefslogtreecommitdiffstats
path: root/debugger.c
diff options
context:
space:
mode:
authorMatt Hunter <m@lfurio.us>2025-09-03 01:21:34 -0400
committerMatt Hunter <m@lfurio.us>2025-09-07 21:03:26 -0400
commit0096d1896083f0df73e086b1e086ec52f610b7bf (patch)
tree91cc89f685a6dedc7ef57e784ff1c3c80df24b03 /debugger.c
parent95364d5a74eb9977b946b4a520eb2624f2c788ab (diff)
downloadmisplays-0096d1896083f0df73e086b1e086ec52f610b7bf.tar.gz
misplays-0096d1896083f0df73e086b1e086ec52f610b7bf.zip
Manually uninstall breakpoints on process forkHEADmaster
Previously, there was a bug on PTRACE_EVENT_FORK in which the forked child process inherits all installed breakpoints due to their interrupt instructions being resident in memory at the time of the fork, but the debugger initializes the new process model with an empty list of breakpoints. There are some differing opinions on what the correct behavior ought to be here, but at a minimum these two realities must be brought into sync to prevent data corruption or any process crash of the fork child. For the time being, manually "uninstall" the residual breakpoint interrupts from a newly forked child that we attach to, leaving it with no breakpoints of any kind. Process model initialization in the debugger is left as-is. Signed-off-by: Matt Hunter <m@lfurio.us>
Diffstat (limited to 'debugger.c')
-rw-r--r--debugger.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/debugger.c b/debugger.c
index 7378298..c3c9fa1 100644
--- a/debugger.c
+++ b/debugger.c
@@ -113,6 +113,15 @@ static void uninstall_breakpoints(struct thread *th) {
}
}
+static void clean_fork_breakpoints(struct thread *th, const struct process *parent) {
+ const struct list *breaks = &parent->breakpoints;
+ for (struct breakpoint *b = breaks->tail; b != breaks->end; b = b->prev) {
+ if (b->installed) {
+ ptrace(PTRACE_POKETEXT, th->id, b->address, b->text);
+ }
+ }
+}
+
static int detect_breakpoint(struct thread *th, int *restart) {
int is_bp = 0; /* at least 1 effective breakpoint at this PC */
int is_user = 0; /* at least 1 user-defined bp at this PC */
@@ -393,6 +402,8 @@ static int wait_thread(struct thread *th) {
//while (!wait_thread(eventth)) {}
dbg_sync(eventproc);
+ clean_fork_breakpoints(eventth, th->proc);
+
th->stopped = 1;
th->signal = 0;
th->doing = 0;