According to ptrace
man page the process should be stopped before trying to detach from it:
Detaching of the tracee is performed by:
ptrace(PTRACE_DETACH, pid, 0, sig);
PTRACE_DETACH is a restarting operation; therefore it requires the tracee to be in ptrace-stop. If the tracee is in signal-delivery- stop, a signal can be injected. Otherwise, the sig parameter may be silently ignored. If the tracee is running when the tracer wants to detach it, the usual solution is to send SIGSTOP (using tgkill(2), to make sure it goes to the correct thread), wait for the tracee to stop in signal- delivery-stop for SIGSTOP and then detach it (suppressing SIGSTOP injection). A design bug is that this can race with concurrent SIGSTOPs. Another complication is that the tracee may enter other ptrace-stops and needs to be restarted and waited for again, until SIGSTOP is seen. Yet another complication is to be sure that the tracee is not already ptrace-stopped, because no signal delivery happens while it is--not even SIGSTOP.
In your example code there is actually no need to call ptrace(PTRACE_CONT, ...)
. You can just detach from the process. If that code belongs to a larger piece of code, then you can just use tgkill()
(or simply kill
if you are not using threads):
ptrace(PTRACE_CONT, ...);
kill(pid, SIGSTOP);
waitpid(pid, NULL, 0);
ptrace(PTRACE_DETACH, ...);