* strace.c (detach) [USE_SEIZE]: If PTRACE_SEIZE API is in use, stop the tracee using PTRACE_INTERRUPT instead of sending it a SIGSTOP. In a subsequent waitpid loop, wait for either SIGSTOP or SIGTRAP.
Signed-off-by: Denys Vlasenko <dvlas...@redhat.com> --- strace.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/strace.c b/strace.c index 87aad48..af8156d 100644 --- a/strace.c +++ b/strace.c @@ -733,7 +733,7 @@ static int detach(struct tcb *tcp) { int error; - int status, sigstop_expected; + int status, stop_expected; if (tcp->flags & TCB_BPTSET) clearbpt(tcp); @@ -749,15 +749,15 @@ detach(struct tcb *tcp) #endif error = 0; - sigstop_expected = 0; + stop_expected = 0; if (tcp->flags & TCB_ATTACHED) { /* * We attached but possibly didn't see the expected SIGSTOP. * We must catch exactly one as otherwise the detached process * would be left stopped (process state T). */ - sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); - error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); + stop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); + error = ptrace(PTRACE_DETACH, tcp->pid, 0, 0); if (error == 0) { /* On a clear day, you can see forever. */ } @@ -769,15 +769,24 @@ detach(struct tcb *tcp) if (errno != ESRCH) perror_msg("detach: checking sanity"); } - else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) { - if (errno != ESRCH) - perror_msg("detach: stopping child"); + else if (!stop_expected) { + /* Process is running, need to stop it first */ + if (use_seize) + error = ptrace(PTRACE_INTERRUPT, tcp->pid, 0, 0); + else + error = my_tkill(tcp->pid, SIGSTOP); + if (!error) + stop_expected = 1; + else if (errno != ESRCH) { + if (use_seize) + perror_msg("detach: ptrace(PTRACE_INTERRUPT, ...)"); + else + perror_msg("detach: stopping child"); + } } - else - sigstop_expected = 1; } - if (sigstop_expected) { + if (stop_expected) { for (;;) { #ifdef __WALL if (waitpid(tcp->pid, &status, __WALL) < 0) { @@ -810,7 +819,9 @@ detach(struct tcb *tcp) /* Au revoir, mon ami. */ break; } - if (WSTOPSIG(status) == SIGSTOP) { + if (WSTOPSIG(status) == SIGSTOP + || WSTOPSIG(status) == SIGTRAP /* may be generated by PTRACE_INTERRUPT stop */ + ) { ptrace_restart(PTRACE_DETACH, tcp, 0); break; } -- 1.8.1.4 ------------------------------------------------------------------------------ This SF.net email is sponsored by Windows: Build for Windows Store. http://p.sf.net/sfu/windows-dev2dev _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel