diff options
author | Malfurious <m@lfurio.us> | 2023-09-29 18:48:41 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2024-04-24 13:31:08 -0400 |
commit | cca59c4d757c99df14978d1778b6be562dd886cd (patch) | |
tree | 5a9b8ba802f1e2acbfe35cc504a0c0f0dad19215 | |
parent | f9584d0417ed8d3fc72d9dcb297b1738fef2d00c (diff) | |
download | misplays-cca59c4d757c99df14978d1778b6be562dd886cd.tar.gz misplays-cca59c4d757c99df14978d1778b6be562dd886cd.zip |
Workaround SIGSTOP on child process startup
The debugger design prefers to use PTRACE_SEIZE instead of
PTRACE_ATTACH, due to the simpler thread control semantics that are
available.
However, to utilize the same featureset for forked processes, we can no
longer use PTRACE_TRACEME to guarantee that the child becomes a tracee
before it execs into the target program.
Manually raising SIGSTOP to act as a synchronization point is
problematic for a couple reasons:
- We need to detect whether the special SIGSTOP was or was not yet
encountered by the time our debugger module attaches and
interrupts the thread. This complicates the dance of input
controls to ensure we are at the exec (and nowhere else) when the
real user takes over the controls.
- The injection of an extra signal circumvents the benefits we hope
to leverage by using the PTRACE_SEIZE semantics. We can no longer
assume that all incoming signals are genuine.
For the time being, sleep in the newly forked child for the scheduler
delay period. This is not bullet-proof, but tends to allow the debugger
module enough time to actually seize the thread before anything
interesting happens. At this point a single dbg_cont() will cause the
child to arrive and stop at the user's exec.
Signed-off-by: Malfurious <m@lfurio.us>
-rw-r--r-- | debugger.c | 3 | ||||
-rw-r--r-- | misplays.c | 7 |
2 files changed, 8 insertions, 2 deletions
@@ -17,7 +17,8 @@ static const int PTRACE_OPTIONS = PTRACE_O_TRACECLONE | - PTRACE_O_TRACEEXIT | + //PTRACE_O_TRACEEXIT | + PTRACE_O_TRACEEXEC | PTRACE_O_TRACESYSGOOD; static int detect_breakpoint(struct thread *th) { @@ -27,9 +27,10 @@ static pid_t dofork(char **argv, struct console *cons) { } if (pid == 0) { + usleep(100000); console_configslave(cons); close_range(STDERR_FILENO+1, ~0U, CLOSE_RANGE_UNSHARE); - raise(SIGSTOP); // ptrace(PTRACE_TRACEME, 0, NULL, NULL); + //raise(SIGSTOP); // ptrace(PTRACE_TRACEME, 0, NULL, NULL); execvp(argv[0], argv); exit(EXIT_FAILURE); } @@ -209,6 +210,10 @@ int main(int argc, char **argv) { list_insert(processes.end, proc); th = proc->threads.head; + if (child) { + dbg_cont(th, PTRACE_CONT); + } + cursinit(); left = newpan(0, 0, 0, 0); right = newpan(0, 0, 0, 0); |