From be1c092cd99a023b3d4178066925b644feb0565f Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 31 May 2020 23:22:22 +0200 Subject: Tracing fork children does not work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- process.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'process.c') diff --git a/process.c b/process.c index c5a09be..056a103 100644 --- a/process.c +++ b/process.c @@ -29,28 +29,31 @@ struct process * add_process(pid_t pid, unsigned long int trace_options) { struct process *proc; - int saved_errno; + int status; + proc = calloc(1, sizeof(*proc)); if (!proc) eprintf("calloc: %s\n"); proc->pid = pid; - if (waitpid(pid, NULL, 0) < 0) { - eprintf("waitpid NULL 0:"); - kill(pid, SIGKILL); - exit(1); - } - if (ptrace(PTRACE_SETOPTIONS, pid, 0, trace_options)) { - saved_errno = errno; - kill(pid, SIGKILL); - errno = saved_errno; - eprintf("ptrace PTRACE_SETOPTIONS %ju 0 ...:", (uintmax_t)pid); - } - if (ptrace(PTRACE_SYSCALL, pid, NULL, 0)) - eprintf("ptrace PTRACE_SYSCALL %ju NULL 0:", (uintmax_t)pid); proc->next = &tail; proc->prev = tail.prev; proc->prev->next = proc; tail.prev = proc; + + while (waitpid(pid, &status, WSTOPPED) != pid) { + if (errno == EINTR) + continue; + eprintf_and_kill(pid, "waitpid %ju WSTOPPED:", (uintmax_t)pid); + } + if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) + eprintf_and_kill(pid, "unexpected return of waitpid %ju WSTOPPED:", (uintmax_t)pid); + if (ptrace(PTRACE_SEIZE, pid, 0, trace_options)) + eprintf_and_kill(pid, "ptrace PTRACE_SEIZE %ju 0 ...:", (uintmax_t)pid); + if (ptrace(PTRACE_INTERRUPT, pid, 0, 0)) + eprintf_and_kill(pid, "ptrace PTRACE_INTERRUPT %ju 0 0:", (uintmax_t)pid); + if (kill(pid, SIGCONT) < 0) + eprintf_and_kill(pid, "kill &ju SIGCONT:", (uintmax_t)pid); + return proc; } -- cgit v1.2.3-70-g09d2