On 06/18/2013 10:36 PM, Dmitry V. Levin wrote: > On Tue, Jun 18, 2013 at 06:18:14PM +0200, Denys Vlasenko wrote: >> * 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 */ >> + ) { > > In case of PTRACE_INTERRUPT this WSTOPSIG(status) is not plain SIGTRAP > but (SIGTRAP | 0x80), which also may happen in other !use_seize cases.
Right, I forgot about that! It's because of TRACESYSGOOD, not SEIZE. The check should be: WSTOPSIG(status) == syscall_trap_sig I'll test and resend the patch. ------------------------------------------------------------------------------ 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