This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: x86 linux GDB and SIGALRM


Mark Kettenis wrote:
> 
>    Date: Mon, 27 Mar 2000 20:00:57 +1000
>    From: Andrew Cagney <ac131313@cygnus.com>
> 
>    Jonathan Larmour wrote:
>    >
>    > I have an x86 Linux program here that uses SIGALRM for regular
>    > periodic "interrupts". SIGVTALRM isn't really precise enough for
>    > it's needs.
>    >
>    > However I noticed that "si" doesn't work - it interferes with the
>    > ptrace/GDB interface. It seems that when
>    > ptrace(PTRACE_SINGLESTEP,...) returns, a SIGALRM is pending, and
>    > the single step gets lost.
>    >
>    > Now this works in GDB 4.18 so this is a regression. But does
>    > anyone have any clues as to what's *meant* to be going on here,
>    > and how I fix GDB?
> 
>    Can anyone independantly confirm/deny this?
> 
> No, but I'd like to see if I can reproduce the problem.  Jonathan, can
> you provide a small test program and detailed instructions (typescript
> of a GDB session) on how to do that?
> 
> I know there are problems with single stepping through signal
> handlers.  These problems were present in 4.18.  They were just masked
> because 4.18 failed to recognize signal handlers.  Fixing it is not
> easy, and will require changes to handle_inferior_event(), that I
> prefer not to make before the 5.0 release.

Sorry for the delay in getting back to you on this. I've attached a test
case for you. Virtual timers are no problem, it's only real-time timers
that cause the problem.

Here's a GDB session. As you can see "stepi"s don't work, but "step"s and
"next"s do.

(gdb) b breakme
Breakpoint 1 at 0x80484ee: file sigalrm.c, line 19.
(gdb) run
Starting program: /n/tikka/home/jlarmour/c/sigalrm

Breakpoint 1, breakme () at sigalrm.c:19
19          struct timeval tv = { 0, 0 };
(gdb) disp/i $pc
1: x/i $eip  0x80484ee <breakme+6>:     movl   $0x0,0xfffffff8(%ebp)
(gdb) si
19          struct timeval tv = { 0, 0 };
1: x/i $eip  0x80484ee <breakme+6>:     movl   $0x0,0xfffffff8(%ebp)
(gdb)
19          struct timeval tv = { 0, 0 };
1: x/i $eip  0x80484ee <breakme+6>:     movl   $0x0,0xfffffff8(%ebp)
(gdb)
19          struct timeval tv = { 0, 0 };
1: x/i $eip  0x80484ee <breakme+6>:     movl   $0x0,0xfffffff8(%ebp)
(gdb) step
21          printf("Got %d alarms\n", alarms);
1: x/i $eip  0x80484fc <breakme+20>:    add    $0xfffffff8,%esp
(gdb) next
Got 8 alarms
22          select(0, NULL, NULL, NULL, &tv);
1: x/i $eip  0x8048512 <breakme+42>:    add    $0xfffffff4,%esp
(gdb) si
22          select(0, NULL, NULL, NULL, &tv);
1: x/i $eip  0x8048512 <breakme+42>:    add    $0xfffffff4,%esp
(gdb)
22          select(0, NULL, NULL, NULL, &tv);
1: x/i $eip  0x8048512 <breakme+42>:    add    $0xfffffff4,%esp
(gdb)

When I changed the itimer interval to 50000usecs from 5000usecs, then I got
mixed behaviour with some instructions stepping working, and some not. If
using e.g. 1 second, instruction stepping appears to work. This is
presumably all due to whether a SIGALRM is pending when ptrace returns.

Jifl
-- 
Red Hat, 35 Cambridge Place, Cambridge, UK. CB2 1NS  Tel: +44 (1223) 728762
"Plan to be spontaneous tomorrow."  ||  These opinions are all my own fault
#include <signal.h>
#include <stddef.h>
#include <sys/time.h>

#define ALRM

volatile int alarms;

static void 
handler( int signum )
{
    alarms++;
}


static void
breakme(void)
{
    struct timeval tv = { 0, 0 };

    printf("Got %d alarms\n", alarms);
    select(0, NULL, NULL, NULL, &tv); 
}

int main(int argc, char *argv[])
{
    struct sigaction act;
    sigset_t set;
    struct itimerval itv;

    act.sa_handler = &handler;
    sigemptyset(&set);
    act.sa_mask = set;
    act.sa_flags = 0;

    sigaction(SIGALRM, &act, NULL);
    sigaction(SIGVTALRM, &act, NULL);

    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 5000;
    itv.it_value.tv_sec = 0;
    itv.it_value.tv_usec = 5000;
#ifdef ALRM
    setitimer(ITIMER_REAL, &itv, NULL);
#else
    setitimer(ITIMER_VIRTUAL, &itv, NULL);
#endif

    for (;;)
        breakme();
    return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]