signal.h - Linux

This is a discussion on signal.h - Linux ; I'm attempting to catch bugs in my program using signal.h with sigsegv. now i know when i'm in gdb i can catch bugs but is there any variable that stores like the file that caused the bug and possible calling ...

+ Reply to Thread
Results 1 to 5 of 5

Thread: signal.h

  1. signal.h

    I'm attempting to catch bugs in my program using signal.h with sigsegv.
    now i know when i'm in gdb i can catch bugs but is there any variable
    that stores like the file that caused the bug and possible calling
    procs? or would that only be left to something with gdb.

  2. Re: signal.h

    David Willoughby wrote:
    > I'm attempting to catch bugs in my program using signal.h with sigsegv.
    > now i know when i'm in gdb i can catch bugs but is there any variable
    > that stores like the file that caused the bug and possible calling
    > procs? or would that only be left to something with gdb.


    If you know the address where the SIGSEGV happened and the program
    was compiled to retain debugging information (e.g. with the '-g'
    option to gcc) you can use the 'addr2line' utility from the
    binutils package to find out the file name, function name and
    line number where the signal happened. You could e.g. invoke
    addr2line from within your program in the signal handler.
    Since addr2line (and gdb) can figure out this information it
    must be stored somewhere in the program - but where exactly
    and in what form I didn't try to find out yet (and it may
    depend on the architecture you're on). If you're curious enough
    reading the source for addr2line will hopefully tell you;-)

    What I found to be the more tricky part is to determine where
    the segmentation fault happened. The man page for sigaction()
    claims that this information is stored in the si_addr member
    of the siginfo structure that the signal handling function
    gets passed when you set SA_SIGINFO in the flag member of the
    structure passed to sigaction(). Unfortunately, on the machine
    I tried it this wasn't the case - si_addr was always NULL. I
    thus had to resort to an ugly and probably very unportable hack
    of reading the ebp register in the signal handler and adding
    68 to that value in order to get the address where the address
    of the instruction that resulted in the signal is stored. I.e.
    I use

    void *segv_addr;
    int *EBP; /* assumes sizeof(int) equals size of pointer */

    asm( "mov %%ebp, %0" : "=g" ( EBP ) );
    segv_addr = ( void * ) * ( EBP + 0x11 );

    I found out about this by trial and error and it probably will
    only work on i386 architectures (I didn't test it on anything
    else). I would be grateful if someone would be able to tell me
    about better and more portable ways of obtaining this bit of
    information, e.g. by getting sigaction() to work as advertised
    in the man pages...
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  3. Re: signal.h

    With a SIGSEGV signal handler you can get some very usefull
    information. You should register you handler with sigaction and the
    SA_SIGINFO flag on. Then, your handler will be like

    static void segv_handler(sig, sip, uap)
    int sig;
    struct siginfo *sip;
    struct ucontext *uap;

    Then, the address of the fault faulting memory reference will be
    (siginfo.si_addr), and whether it was a read or write fault will be
    given by (write_fault = uap->uc_mcontext.gregs[REG_ERR] & 2). As far I
    am concerned both are valid for i386 and x86_64.

    For i386, the address of the faulting instruction will be
    (uap->uc_mcontext.gregs[REG_EIP] ), but it does not work for x86_64.
    Does any one know how to get thet address of the SIGSEGV faulting
    instruction for x86_64????

    Luiz


  4. Re: signal.h

    garfo2006@gmail.com wrote:
    > With a SIGSEGV signal handler you can get some very usefull
    > information. You should register you handler with sigaction and the
    > SA_SIGINFO flag on. Then, your handler will be like


    > static void segv_handler(sig, sip, uap)
    > int sig;
    > struct siginfo *sip;
    > struct ucontext *uap;


    > Then, the address of the fault faulting memory reference will be
    > (siginfo.si_addr),


    I tried exactly this but unfortunately the si_addr member of the
    siginfo_t structure was always NULL (on i386). I have no idea why
    and also didn't find an explanation...

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  5. Re: signal.h

    > I tried exactly this but unfortunately the si_addr member of the
    > siginfo_t structure was always NULL (on i386). I have no idea why
    > and also didn't find an explanation...


    It has been working with me, with Linux 2.6 (CentOS 4) and SA_SIGINFO.
    I am travelling right now, but when I get back to the office I will
    check it.

    Luiz


+ Reply to Thread