aboutsummaryrefslogtreecommitdiffstats
path: root/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'process.c')
-rw-r--r--process.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/process.c b/process.c
index 7e7a54f..5d88a04 100644
--- a/process.c
+++ b/process.c
@@ -26,7 +26,7 @@ find_process(pid_t pid)
struct process *
-add_process(pid_t pid, unsigned long int trace_options)
+add_process(pid_t pid, pid_t leader, unsigned long int trace_options)
{
struct process *proc;
int status, sig;
@@ -35,12 +35,16 @@ add_process(pid_t pid, unsigned long int trace_options)
if (!proc)
eprintf("calloc: %s\n");
proc->pid = pid;
+ proc->thread_leader = leader;
proc->next = &tail;
proc->prev = tail.prev;
proc->prev->next = proc;
tail.prev = proc;
- while (waitpid(pid, &status, WSTOPPED) != pid) {
+ if (!leader)
+ leader = pid;
+
+ while (waitpid(pid, &status, WUNTRACED) != pid) {
if (errno == EINTR)
continue;
eprintf_and_kill(pid, "waitpid %ju <buffer> WSTOPPED:", (uintmax_t)pid);
@@ -48,15 +52,15 @@ add_process(pid_t pid, unsigned long int trace_options)
sig = WIFSTOPPED(status) ? WSTOPSIG(status) : 0;
if (sig == SIGSTOP) {
- if (ptrace(PTRACE_SEIZE, pid, 0, trace_options))
- eprintf_and_kill(pid, "ptrace PTRACE_SEIZE %ju 0 ...:", (uintmax_t)pid);
+ if (ptrace(PTRACE_SEIZE, pid, NULL, trace_options))
+ eprintf_and_kill(pid, "ptrace PTRACE_SEIZE %ju NULL ...:", (uintmax_t)pid);
if (ptrace(PTRACE_INTERRUPT, pid, NULL, 0))
eprintf_and_kill(pid, "ptrace PTRACE_INTERRUPT %ju NULL 0:", (uintmax_t)pid);
- if (kill(pid, SIGCONT) < 0)
- eprintf_and_kill(pid, "kill &ju SIGCONT:", (uintmax_t)pid);
+ if (tgkill(leader, pid, SIGCONT) < 0)
+ eprintf_and_kill(pid, "tgkill %ju %ju SIGCONT:", (uintmax_t)leader, (uintmax_t)pid);
} else if (sig == SIGTRAP && status & PTRACE_EVENT_STOP << 16) {
- if (ptrace(PTRACE_SYSCALL, pid, NULL, 0))
- eprintf_and_kill(pid, "ptrace PTRACE_SYSCALL %ju NULL 0:", (uintmax_t)pid);
+ if (ptrace(PTRACE_SETOPTIONS, pid, NULL, trace_options))
+ eprintf_and_kill(pid, "ptrace PTRACE_SETOPTIONS %ju NULL ...:", (uintmax_t)pid);
} else {
eprintf_and_kill(pid, "unexpected return of waitpid %ju <buffer> WSTOPPED: %#x\n", (uintmax_t)pid, status);
}