* 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

Reply via email to