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.
That is, the right check seems to be
        WSTOPSIG(status) == SIGSTOP ||
        (use_seize && WSTOPSIG(status) == (SIGTRAP | 0x80))
It also passes both tests/detach-sleeping and tests/detach-stopped.


-- 
ldv

Attachment: pgpPo6bglE0t9.pgp
Description: PGP signature

------------------------------------------------------------------------------
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