More trouble with i386 EFLAGS and ptrace

From: Daniel Jacobowitz (dan_at_debian.org)
Date: 03/06/05

  • Next message: Pavel Machek: "Re: BIOS overwritten during resume (was: Re: Asus L5D resume on battery power)"
    Date:	Sun, 6 Mar 2005 14:38:41 -0500
    To: Linus Torvalds <torvalds@osdl.org>, linux-kernel@vger.kernel.org
    
    

    It looks like the changes to preserve eflags when single-stepping don't work
    right with signals. Take this test case:

    <snip>
    #include <signal.h>
    #include <unistd.h>

    volatile int done;

    void handler (int sig)
    {
      done = 1;
    }

    int main()
    {
      while (1)
        {
          done = 0;
          signal (SIGALRM, handler);
          alarm (1);
          while (!done);
        }
    }
    <snip>

    And this GDB session:

    (gdb) b 18
    Breakpoint 1 at 0x804840d: file test.c, line 18.
    (gdb) r
    Starting program: /home/drow/eflags/test

    Breakpoint 1, main () at test.c:18
    18 while (!done);
    (gdb) p/x $eflags
    $1 = 0x200217
    (gdb) c
    Continuing.

    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x08048414 in main () at test.c:18
    18 while (!done);
    (gdb) p/x $eflags
    $2 = 0x200302

    There's an implied delay before the "c" which is long enough for the signal
    handler to become pending.

    The reason this happens is that when the inferior hits a breakpoint, the
    first thing GDB will do is remove the breakpoint, single-step past it, and
    reinsert it. So GDB does a PTRACE_SINGLESTEP, and the kernel invokes the
    signal handler (without single-step - good so far). When the signal handler
    returns, we've lost track of the fact that ptrace set the single-step flag,
    however. So the single-step completes and returns SIGTRAP to GDB. GDB is
    expecting a SIGTRAP and reinserts the breakpoint. Then it resumes the
    inferior, but now the trap flag is set in $eflags. So, oops, the continue
    acts like a step instead.

    What to do? We need to know when we restore the trap bit in sigreturn
    whether it was set by ptrace or by the application (possibly including by
    the signal handler).

    Andrew, serious kudos for GDB's sigstep.exp, which uncovered this problem
    (through a much more complicated test - I may add the smaller one).

    -- 
    Daniel Jacobowitz
    CodeSourcery, LLC
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    

  • Next message: Pavel Machek: "Re: BIOS overwritten during resume (was: Re: Asus L5D resume on battery power)"

    Relevant Pages

    • Re: unsafe functions from signal handler
      ... I suspect you are right about that. ... You can siglongjmp out of the handler. ... of signals to a process blocked in wait. ... In gdb, I ...
      (comp.os.linux.development.apps)
    • Re: Using SetConsoleCtrlHandler
      ... "bare minimum" principal should work even in multithreaded POSIX apps, ... you rely on recursive lock acqusition in your "signal handler" - hard to ... POSIX signals to POSIX processes". ... "Kernel mode APCs interrupt a thread and execute a procedure without ...
      (microsoft.public.win32.programmer.kernel)
    • Re: SetConsoleCtrlHandler
      ... This modified handler does not call ... signals. ... This allows the service to continue running after the user logs ... If the service installs its own console control handler, ...
      (microsoft.public.win32.programmer.kernel)
    • Re: pitfalls of signals
      ... If you have a signal handler that was invoked as a result of your program ... in that case you've invoked undefined behavior ... without invoking undefined behavior ... -Temporarily block a set of signals that includes the one the handler ...
      (comp.lang.c)
    • Re: Mars Rover Controlled By Java
      ... When handling signals Ada provides a higher level abstraction that ... -- Defines the interface for a signal handler ... task Responder is ... interrupt is handled only once. ...
      (comp.programming)