diff --git a/src/basset.cpp b/src/basset.cpp index d30182d..632787e 100644 --- a/src/basset.cpp +++ b/src/basset.cpp @@ -11,6 +11,7 @@ #undef PTRACE_SYSCALL #undef PTRACE_TRACEME +#include #include using std::cerr; @@ -26,6 +27,27 @@ int main(int argc, char *argv[]) { int wstatus; + if (wait(&wstatus) == -1) { + perror("cannot wait()"); + return -1; + } + + if (!WIFSTOPPED(wstatus) || WSTOPSIG(wstatus) != SIGSTOP) { + cerr << "unexpected state of child\n"; + return -1; + } + + if (ptrace(PTRACE_SETOPTIONS, pid, nullptr, + PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | + PTRACE_O_TRACEEXEC | PTRACE_O_TRACESYSGOOD) == -1) { + perror("cannot ptrace(PTRACE_SETOPTIONS)"); + return -1; + } + + if (ptrace(PTRACE_SYSCALL, pid, nullptr, nullptr) == -1) { + perror("cannot ptrace(PTRACE_CONT)"); + } + while (auto pid = wait(&wstatus)) { if (pid == -1) { perror("cannot wait()"); @@ -37,13 +59,6 @@ int main(int argc, char *argv[]) { } else if (WIFSTOPPED(wstatus)) { cerr << pid << " stopped\n"; - if (ptrace(PTRACE_SETOPTIONS, pid, nullptr, - PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | - PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC | - PTRACE_O_TRACESYSGOOD) == -1) { - perror("cannot ptrace(PTRACE_SETOPTIONS)"); - } - ptrace_syscall_info data; if (auto res = @@ -85,6 +100,12 @@ int main(int argc, char *argv[]) { return -1; } + // allow parent to ptrace(PTRACE_SETOPTIONS) + if (raise(SIGSTOP) != 0) { + perror("cannot raise(SIGSTOP)"); + return -1; + } + execvp(*argv, argv); // on success, execve() does not return perror("cannot execve()");