Bug 162774 - strace ignores int3 SIGTRAP
strace ignores int3 SIGTRAP
Product: Fedora
Classification: Fedora
Component: strace (Show other bugs)
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Dmitry V. Levin
Brian Brock
: FutureFeature, Upstream
Depends On:
  Show dependency treegraph
Reported: 2005-07-08 11:49 EDT by John Reiser
Modified: 2012-12-07 18:17 EST (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2012-12-07 18:17:05 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Proof-of-concept patch (2.81 KB, patch)
2008-09-10 08:53 EDT, Denys Vlasenko
no flags Details | Diff
Kernel patch to make ALL ptrace SIGTRAPs to be affected by PTRACE_O_TRACESYSGOOD (17.98 KB, patch)
2008-09-24 09:05 EDT, Denys Vlasenko
no flags Details | Diff
Cleaned up and better tested strace patch (4.11 KB, patch)
2008-12-16 15:30 EST, Denys Vlasenko
no flags Details | Diff

  None (edit)
Description John Reiser 2005-07-08 11:49:40 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4

Description of problem:
This program runs differently under strace in constrast to under bash.  strace does not report the SIGTRAP that the kernel sends in response to executing 'int3'.  strace also does not terminate execution, which is the default policy for SIGTRAP.

----- int3.S
_start: .globl _start

        movl $42,%ebx
        movl $1,%eax
        int $0x80
gcc -nostartfiles -nostdlib -o int3 int3.S

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Compile the program in the Description.
2. Execute directly under a shell.
3. Execute under strace.

Actual Results:  $ ./int3
Trace/breakpoint trap   ## good; expected.
$ strace ./int3
execve("./int3", ["./int3"], [/* 33 vars */]) = 0
_exit(42)                               = ?   ## bad; no SIGTRAP reported

Expected Results:  strace should have reported the SIGTRAP caused by the int3 instruction.  Execution should have aborted (the default policy for SIGTRAP), instead of continuing through the exit(42).

Additional info:

This is a refinement of bug 160915.
Comment 1 Roland McGrath 2005-07-19 02:31:54 EDT
strace has always swallowed SIGTRAPs, so I am marking this as an enhancement.
Comment 2 Christian Iseli 2007-01-22 05:26:23 EST
This report targets the FC3 or FC4 products, which have now been EOL'd.

Could you please check that it still applies to a current Fedora release, and
either update the target product or close it ?

Comment 3 John Reiser 2007-01-22 15:26:13 EST
The behavior persists in Fedora Core 6, using
Namely, strace ignores int3.  This also happens in 32-bit mode on x86_64.  I
changed the Version of this bugzilla report to fc6.
Comment 4 Bug Zapper 2008-04-03 21:58:38 EDT
Fedora apologizes that these issues have not been resolved yet. We're
sorry it's taken so long for your bug to be properly triaged and acted
on. We appreciate the time you took to report this issue and want to
make sure no important bugs slip through the cracks.

If you're currently running a version of Fedora Core between 1 and 6,
please note that Fedora no longer maintains these releases. We strongly
encourage you to upgrade to a current Fedora release. In order to
refocus our efforts as a project we are flagging all of the open bugs
for releases which are no longer maintained and closing them.

If this bug is still open against Fedora Core 1 through 6, thirty days
from now, it will be closed 'WONTFIX'. If you can reporduce this bug in
the latest Fedora version, please change to the respective version. If
you are unable to do this, please add a comment to this bug requesting
the change.

Thanks for your help, and we apologize again that we haven't handled
these issues to this point.

The process we are following is outlined here:

We will be following the process here:
http://fedoraproject.org/wiki/BugZappers/HouseKeeping to ensure this
doesn't happen again.

And if you'd like to join the bug triage team to help make things
better, check out http://fedoraproject.org/wiki/BugZappers
Comment 5 John Reiser 2008-04-04 20:24:22 EDT
Please change Version to rawhide; bugzilla won't let me.

The problem persists in Fedora 9 Beta kernel-2.6.25-0.185.rc7.git6.fc9.x86_64
and strace-4.5.16-5.fc9.x86_64.
Comment 6 Denys Vlasenko 2008-09-10 08:53:06 EDT
Created attachment 316309 [details]
Proof-of-concept patch

This patch sets PTRACE_O_TRACESYSGOOD option for traced child. Kernel will flag ptrace-related signals by setting bit 0x80 in signo.

Patch contains some debugging code nad comments which are easy to spot.

Patch is run-tested. int3 example:

# /root/srcdevel/strace/fix/strace.t1/strace ./int3
execve("./int3", ["./int3"], [/* 54 vars */]bogus SIGTRAP: made it SIGTRAP80
) = 0
--- SIGTRAP (Trace/breakpoint trap) @ 0 (0) ---
+++ killed by SIGTRAP +++

Also tried running e.g. "ls -l" and it seems that stracing of normal programs is not affected.

In this patch, "strace -p" is not using PTRACE_O_TRACESYSGOOD trick yet.
Comment 7 Denys Vlasenko 2008-09-10 08:58:30 EDT
> In this patch, "strace -p" is not using PTRACE_O_TRACESYSGOOD trick yet.

Actually, it does:

# /root/srcdevel/strace/fix/strace.t1/strace -o zz -p 6252
Process 6252 attached - interrupt to quit

No additional patching needed.
Comment 8 Denys Vlasenko 2008-09-10 11:44:57 EDT
The "bug" of extra SIGTRAP which patch works around is not really a bug, it's a feature of execve:

       execve - execute program
       If  the current program is being ptraced, a SIGTRAP is sent to it after
       a successful execve().

This extra SIGTRAP is not affected by PTRACE_O_TRACESYSGOOD option. In my opinion, this SIGTRAP should not be passed to straced program as this may change its behavior, so handling of this SIGTRAP as coded in the patch is correct, only comment

+		/* Kernel bug (observed on 2.6.25 x86_64):
+		 * even if we set PTRACE_O_TRACESYSGOOD option,
+		 * after execve(), post-syscall ptrace-generated SIGTRAP
+		 * has signo == SIGTRAP, not (SIGTRAP | 0x80)!
+		 * Detect it by looking at siginfo.
+		 */

nees changing. I am not sure whether the detection is future-proof (why kernel doesn't fill in correct si.si_signo? What would happen if it would be fixed in kernel? etc), but so far it works.
Comment 9 Denys Vlasenko 2008-09-10 12:41:01 EDT
FYI: SIGTRAP after execve is generated by kernel here: include/linux/tracehook.h

static inline void tracehook_report_exec(struct linux_binfmt *fmt,
                                         struct linux_binprm *bprm,
                                         struct pt_regs *regs)
        if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
            unlikely(task_ptrace(current) & PT_PTRACED))
                send_sig(SIGTRAP, current, 0);

(found in http://lkml.org/lkml/2008/9/8/424 post)
Comment 10 Denys Vlasenko 2008-09-24 09:05:15 EDT
Created attachment 317582 [details]
Kernel patch to make ALL ptrace SIGTRAPs to be affected by PTRACE_O_TRACESYSGOOD

The idea behind PTRACE_O_TRACESYSGOOD is to make it possible to distinguish real SIGTRAP (like int3 instruction on x86) and ptrace generated one.

Current wording of ptrace manpage says that PTRACE_O_TRACESYSGOOD should affect only PTRACE_SYSCALL related traps. This completely negates the whole idea of PTRACE_O_TRACESYSGOOD, since now we can't detect other SIGTRAPs. In particular, one which is emitted after successful execve().

I propose to re-formulate ptrace description so that PTRACE_O_TRACESYSGOOD affects all ptrace-related SIGTRAPs which otherwise would be indistinguishable from ordinary ones.

The patch implements this. The patch is against current git+utrace patch.

I tested it with strace patched with previously attatched strace patch and verified that ugly workaround to detect post-execve() SIGTRAP is not needed anymore.

This is where it is fiexd for utrace:

-       send_sig(SIGTRAP, task, 0);
+       send_sig(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0),
+               task, 0);

and ordinary ptrace:

-       if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
-           unlikely(task_ptrace(current) & PT_PTRACED))
-               send_sig(SIGTRAP, current, 0);
+       /* if PTRACE_O_TRACEEXEC option is active */
+       if (ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0))
+               return;
+       if (unlikely(task_ptrace(current) & PT_PTRACED)) {
+               ptrace_notify_SIGTRAP80();
+       }

Patch also makes other SIGTRAPs send (SIGTRAP | 0x80), like single-stepping. Not tested.
Comment 11 Denys Vlasenko 2008-12-16 15:30:23 EST
Created attachment 327158 [details]
Cleaned up and better tested strace patch

I posted it to strace-devel@lists.sourceforge.net, subject line is

[PATCH] correctly handle "kill -TRAP $straced_programs_pid" and int3
Comment 12 Denys Vlasenko 2009-01-02 08:43:22 EST
The fix is in upstream CVS now. Taking into account that this isn't a hot potato (strace users were coping with inability to handle SIGTRAPs for many years), I am contemplating just waiting till upstream code will trickle into Fedora updates / new Fedora release.
Comment 13 Roland McGrath 2009-01-02 14:58:42 EST
Since we are upstream maintainers, for Fedora strace I have always used fresh upstream releases.  Neither this nor other bugs are so urgent they can't wait for that.
Comment 14 Denys Vlasenko 2011-05-23 15:41:47 EDT
Fixed in git:

commit 3454e4b463e6c22c7ea8c5461ef5a077f4650a54
Author: Denys Vlasenko <dvlasenk@redhat.com>
Date:   Mon May 23 21:29:03 2011 +0200

    Properly handle real SIGTRAPs.

    * defs.h (ptrace_setoptions): Variable renamed to ptrace_setoptions_followfork.
    * process.c (internal_fork): Ditto.
    * strace.c (ptrace_setoptions_for_all): New variable.
    (SYSCALLTRAP): New variable.
    (error_msg_and_die): New function.
    (test_ptrace_setoptions_for_all): New function.
    (main): Call test_ptrace_setoptions_for_all() at init.
    (handle_ptrace_event): Handle PTRACE_EVENT_EXEC (by ignoring it).
    (trace): Check events and set ptrace options without -f too.
    Check WSTOPSIG(status) not for SIGTRAP, but for SYSCALLTRAP.
Comment 15 Fedora Admin XMLRPC Client 2012-12-07 16:15:04 EST
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 16 Dmitry V. Levin 2012-12-07 18:17:05 EST
It was fixed in strace-4.7-1.

Note You need to log in before you can comment on or make changes to this bug.