[PATCH] make strace handle SIGTRAP properly

Denys Vlasenko dvlasenk at redhat.com
Mon Jun 20 19:24:15 UTC 2011


if (followfork && (tcp->parent == NULL))On Mon, 2011-06-20 at 22:28
+0400, Dmitry V. Levin wrote:
> On Mon, Jun 20, 2011 at 05:06:35PM +0200, Denys Vlasenko wrote:
> > On Mon, 2011-06-20 at 04:07 +0400, Dmitry V. Levin wrote:
> [...]
> > > Unfortunately, this commit introduced a severe regression: starting with
> > > v4.6-5-g3454e4b, strace -f follows vfork() with low probability.
> > > Spotted with gcc which uses vfork().
> > > 
> > > Test case:
> > > $ for i in `seq 0 99`; do ./strace -qf -o"|grep -c 'execve(\"'" -- sh -c 'echo "#include <stdio.h>" |gcc -xc -c -o/dev/null -'; done |sort -n |uniq -c
> > >      83 3
> > >      17 7
> > 
> > Looking at it.
> > So far I don't have complete analysis, but I noticed something
> > which may lead to understanding: strace sometimes exits sooner than
> > piped-to log process:
> 
> No, that is not related to -o option processing.

Yes, I also determined it. I have a much simpler reproducer by now...

But most importantly, I think I found the bug:


                        int options = ptrace_setoptions_for_all;
                        if (followfork)    // && (tcp->parent == NULL))  <=== HERE
                                options |= ptrace_setoptions_followfork;
                        if (options) {
                                if (debug)
                                        fprintf(stderr, "setting opts %x on pid %d\n", options, tcp->pid);
                                if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, options) < 0) {
                                        if (errno != ESRCH) {
                                                /* Should never happen, really */
                                                error_msg_and_die("PTRACE_SETOPTIONS");
                                        }
                                }
                        }

The check (tcp->parent == NULL) in old code was meant to check
"if we are not a child created by auto-attach" - in this case,
options need to be set on the child; otherwise they are inherited
and do not need to be set.

I misunderstood the check and if tcp->parent is not NULL, I was
setting only ptrace_setoptions_for_all bits!

Simple solution is depicted above - just comment out "&& (tcp->parent == NULL))".

I will test the "more optimal" solution which does the check, but sets correct opts.

Meanwhile, can you confirm that commenting-out works for you too?

-- 
vda






More information about the Strace-devel mailing list