[PATCH] make strace handle SIGTRAP properly

Dmitry V. Levin ldv at altlinux.org
Mon Jun 20 00:07:10 UTC 2011


On Fri, May 20, 2011 at 06:02:14PM +0200, Denys Vlasenko wrote:
> On Fri, 2011-05-20 at 14:08 +0200, Denys Vlasenko wrote:
> > Hi,
> > 
> > (please don't remove me from CC: when replying)
> > 
> > During recent lkml discussions about fixing some long-standing problems
> > with ptrace, I had to look in strace source and experiment with it a
> > bit. (CC-ing some participants).
> > 
> > One irritating thing I noticed is that we *still* don't handle
> > user-generated SIGTRAPs. There are users who do want that to work:
> > 
> > https://bugzilla.redhat.com/show_bug.cgi?id=162774
> > 
> > Currently, strace "handles" SIGTRAP by code like this:
> > 
> > #if defined (I386)
> >         if (upeek(tcp, 4*EAX, &eax) < 0)
> >                 return -1;
> >         if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
> >                 if (debug)
> >                         fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
> >                 return 0;
> >         }
> > #elif ...
> > 
> > Think what will happen if SIGTRAP arrives while process is in userspace
> > and eax happened to contain value equal to -ENOSYS...
> > 
> > In order to make it work properly, that is, to detect SIGTRAPs just like
> > we do with any other signals, we need to use ptrace(PTRACE_SETOPTIONS,
> > PTRACE_O_TRACESYSGOOD). Otherwise, syscall traps are indistinguishable
> > from real SIGTRAPs. Well, there is some extremely fragile and/or
> > arch-specific way way to distinguish them by looking at GETSIGINFO
> > results or registers (see above), but why should we bother? Linux ptrace
> > has PTRACE_O_TRACESYSGOOD for many years now, we _can_ use it.
> > 
> > Another twist in this story is that pesky extra SIGTRAP generated after
> > execve. If we start handling real SIGTRAPs, we should not be fooled by
> > it.
> > 
> > And again, even though there may be a difficult way to detect it, I
> > think we should use the easy one: PTRACE_O_TRACEEXEC option. It disables
> > post-execve SIGTRAP (and enables intra-execve PTRACE_EVENT_EXEC, which
> > is easily distinguishable form other stops, so we can ignore it easily).
> > 
> > Roland's worry was that in some old kernels ptrace(PTRACE_SETOPTIONS)
> > was working, but the options themselves were buggy. I trust him that
> > there were such kernels, but it's history now, right?
> > So, I propose to attempt ptrace(PTRACE_SETOPTIONS) only on relatively
> > recent kernels. (say, starting from 2.6.30? (arbitrarily chosen))
> > 
> > Any objections to this plan?
> 
> And here's the patch against current strace git. Run-tested.

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


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20110620/2cf9338a/attachment.bin>


More information about the Strace-devel mailing list