diff options
author | Malfurious <m@lfurio.us> | 2023-10-09 16:08:34 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2024-04-24 13:31:08 -0400 |
commit | ee936125622325a4b33bafe336b44e44a24ce1aa (patch) | |
tree | 42d310424c380b17d378e1f1ad0975b1a59de725 | |
parent | 80a43bdbdeee87605fdbcdd79195edc98b98fd1d (diff) | |
download | misplays-ee936125622325a4b33bafe336b44e44a24ce1aa.tar.gz misplays-ee936125622325a4b33bafe336b44e44a24ce1aa.zip |
Handle PTRACE_EVENT_EXIT to capture a final state snapshot
Also, it is now possible for interrupt_all_threads to fail to stop
threads in uninterruptable sleep (eg: the main thread during execve).
This may happen in more general cases as well, but it is now common
enough in that case to worry about.
Signed-off-by: Malfurious <m@lfurio.us>
-rw-r--r-- | debugger.c | 14 |
1 files changed, 12 insertions, 2 deletions
@@ -16,6 +16,7 @@ static const int PTRACE_OPTIONS = PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC | + PTRACE_O_TRACEEXIT | PTRACE_O_TRACESYSGOOD; static const int PTRACE_CHILD_OPTIONS = PTRACE_OPTIONS | PTRACE_O_EXITKILL; @@ -258,7 +259,7 @@ static void resume_threads(struct process *proc) { int once = 0; for (struct thread *th = threads->head; th != threads->end; th = th->next) { - if (th->doing == PTRACE_SINGLESTEP) { + if (th->stopped && th->doing == PTRACE_SINGLESTEP) { ptrace(PTRACE_SINGLESTEP, th->id, NULL, th->signal); th->stopped = 0; th->signal = 0; @@ -267,7 +268,7 @@ static void resume_threads(struct process *proc) { } for (struct thread *th = threads->head; th != threads->end; th = th->next) { - if (th->doing && th->doing != PTRACE_SINGLESTEP) { + if (th->stopped && th->doing && th->doing != PTRACE_SINGLESTEP) { if (!once) { usleep(SCHEDULER_DELAY); once = 1; @@ -349,6 +350,15 @@ static int wait_thread(struct thread *th) { th->state = NULL; return 1; + case SIGTRAP | (PTRACE_EVENT_EXIT << 8): + th->stopped = 1; + th->signal = 0; + th->doing = PTRACE_CONT; + th->donext = 0; + strcpy(th->status, "EXITING"); + th->state = NULL; + return 1; + case SIGTRAP | (PTRACE_EVENT_STOP << 8): th->stopped = 1; th->signal = 0; |