From c5211aca9ea40487dc4299423f735da04630fcc6 Mon Sep 17 00:00:00 2001 From: Malfurious Date: Mon, 25 Sep 2023 00:39:44 -0400 Subject: Fix capture_state edge cases Use `th->state == NULL` as an indicator that each thread's state is capturable, discard use of the `all` parameter. Signed-off-by: Malfurious --- debugger.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/debugger.c b/debugger.c index 956b065..1ad88c8 100644 --- a/debugger.c +++ b/debugger.c @@ -157,14 +157,21 @@ static void capture_state_thread(struct thread *th) { } static void capture_state(struct thread *th, int all) { - if (all) { - struct list *threads = &th->proc->threads; - for (struct thread *t = threads->head; t != threads->end; t = t->next) { + (void)all; + struct list *threads = &th->proc->threads; + for (struct thread *t = threads->head; t != threads->end; t = t->next) { + if (!t->state) { capture_state_thread(t); } - } else { - capture_state_thread(th); } + //if (all) { + // struct list *threads = &th->proc->threads; + // for (struct thread *t = threads->head; t != threads->end; t = t->next) { + // capture_state_thread(t); + // } + //} else { + // capture_state_thread(th); + //} } static struct process *new_process(pid_t pid, int child) { @@ -268,6 +275,7 @@ struct process *dbg_attach(pid_t pid, int child) { //global_thread = proc->threads.head; interrupt_all_threads(proc); + capture_state(proc->threads.head, 0); return proc; } @@ -343,6 +351,7 @@ int dbg_wait(struct thread *th, int recursion) { th->signal = 0; th->cont = 0; th->status = "CLONE EVENT"; + th->state = NULL; if (!recursion) { stopped = interrupt_all_threads(th->proc); @@ -357,6 +366,7 @@ int dbg_wait(struct thread *th, int recursion) { th->signal = 0; /* eventmsg has exit code, but would inject sig */ th->cont = 0; th->status = "EXIT EVENT"; + th->state = NULL; if (!recursion) { stopped = interrupt_all_threads(th->proc); @@ -371,6 +381,7 @@ int dbg_wait(struct thread *th, int recursion) { th->signal = 0; th->cont = 0; th->status = "STOP EVENT"; + th->state = NULL; if (!recursion) { stopped = interrupt_all_threads(th->proc); @@ -385,6 +396,7 @@ int dbg_wait(struct thread *th, int recursion) { th->signal = 0; th->cont = 0; th->status = "SYSCALL EVENT"; + th->state = NULL; if (!recursion) { stopped = interrupt_all_threads(th->proc); @@ -413,6 +425,9 @@ int dbg_wait(struct thread *th, int recursion) { /* todo: Test two threads hitting a breakpoint at * the same time. */ int restart = detect_breakpoint(th); + if (!restart) { + th->state = NULL; + } if (!recursion) { stopped = interrupt_all_threads(th->proc); @@ -434,6 +449,7 @@ int dbg_wait(struct thread *th, int recursion) { th->signal = WSTOPSIG(status); th->cont = 0; th->status = "SIGNAL DELIVERY"; + th->state = NULL; if (!recursion) { stopped = interrupt_all_threads(th->proc); -- cgit v1.2.3