> >
> > 2. unwinding with -fomit-frame-pointer doesn't work and often
> > segfaults.
> >
> 
> Which version of libunwind are you testing?

I first noticed problems with whatever Fedora rawhide has.  So I
built 0.99-alpha myself and still have the same problems.

Attached is a test-case.  If you build it with -fomit-frame-pointer,
and run, it crashes inside libunwind almost immediately.

If you build it without -fomit-frame-pointer, then it doesn't crash,
but something is still going wrong with the unwinding; you hit
dwarf_find_proc_info with some wierd addresses:

IP=0xbfb3c5a3 not found
IP=0xbfb3c5d3 not found
IP=0xbfb3c5af not found
IP=0xbfb3c5bb not found
IP=0xbfb3c5d3 not found
IP=0xbfb3c5eb not found
IP=0xbfb3c5bb not found

That's somewhere above the stack and definately not a real IP...

Ralph.
/*
This program crashes inside libunwind (the exact stack trace will vary):

#0  access_mem (as=0x1572a0, addr=5, val=0xbfbfcfd8, write=0, arg=0xbfbfd240) at x86/Ginit.c:116
#1  0x001504b3 in _Ux86_is_signal_frame (cursor=0xbfbfd044) at x86/Gis_signal_frame.c:60
#2  0x00150ec5 in _Ux86_step (cursor=0xbfbfd044) at x86/Gstep.c:54
#3  0x080486bb in signal_handler ()
#4  <signal handler called>
#5  0x080486f3 in fib2 ()
#6  0x00000005 in ?? ()
#7  0x0804870c in fib4 ()
#8  0x08048737 in fib6 ()
#9  0x0804875b in fib8 ()
#10 0x08048766 in fib9 ()
#11 0x08048778 in fib10 ()
#12 0x0804878a in fib11 ()
#13 0x080487b5 in fib13 ()
....

The fact that gdb thinks frame 6 is wierd makes me suspect gcc has
emited bogus unwind info?


When compiled with:

gcc -Wall -Werror  -fasynchronous-unwind-tables -fomit-frame-pointer  -o unwind-test unwind-test.o /usr/lib/libunwind.so /usr/lib/libunwind-x86.so 

*/

#include <libunwind.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#define CHECK(s) check(s, #s "\n")
static int check (int s, const char * w)
{
    if (s >= 0)
        return s;
    write (2, w, strlen (w));
    abort();
}
static void signal_handler (int signal, siginfo_t * info, void * p)
{
    unw_context_t context;
    CHECK (unw_getcontext (&context));

    unw_cursor_t cursor;
    CHECK (unw_init_local (&cursor, &context));
    do {
    }
    while (CHECK (unw_step (&cursor)) > 0);
}


/* A whole load of dummy functions to chew up CPU and stack space.  */

int fib0 (void)
{
    return 0;
}

int fib1 (void)
{
    return 1;
}

#define FIB(A,B,C) int A (void) { return B() + C(); }

FIB(fib2,fib1,fib0)
FIB(fib3,fib2,fib1)
FIB(fib4,fib3,fib2)
FIB(fib5,fib4,fib3)
FIB(fib6,fib5,fib4)
FIB(fib7,fib6,fib5)
FIB(fib8,fib7,fib6)
FIB(fib9,fib8,fib7)
FIB(fib10,fib9,fib8)
FIB(fib11,fib10,fib9)

FIB(fib12,fib11,fib10)
FIB(fib13,fib12,fib11)
FIB(fib14,fib13,fib12)
FIB(fib15,fib14,fib13)
FIB(fib16,fib15,fib14)
FIB(fib17,fib16,fib15)
FIB(fib18,fib17,fib16)
FIB(fib19,fib18,fib17)
FIB(fib20,fib19,fib18)
FIB(fib21,fib20,fib19)

FIB(fib22,fib21,fib20)
FIB(fib23,fib22,fib21)
FIB(fib24,fib23,fib22)
FIB(fib25,fib24,fib23)
FIB(fib26,fib25,fib24)
FIB(fib27,fib26,fib25)
FIB(fib28,fib27,fib26)
FIB(fib29,fib28,fib27)
FIB(fib30,fib29,fib28)
FIB(fib31,fib30,fib29)

FIB(fib32,fib31,fib30)
FIB(fib33,fib32,fib31)
FIB(fib34,fib33,fib32)
FIB(fib35,fib34,fib33)
FIB(fib36,fib35,fib34)
FIB(fib37,fib36,fib35)
FIB(fib38,fib37,fib36)
FIB(fib39,fib38,fib37)
FIB(fib40,fib39,fib38)
FIB(fib41,fib40,fib39)

FIB(fib42,fib41,fib40)
FIB(fib43,fib42,fib41)
FIB(fib44,fib43,fib42)
FIB(fib45,fib44,fib43)
FIB(fib46,fib45,fib44)
FIB(fib47,fib46,fib45)
FIB(fib48,fib47,fib46)
FIB(fib49,fib48,fib47)
FIB(fib50,fib49,fib48)
FIB(fib51,fib50,fib49)


int main()
{
    /* Get SIGPROF to run our signal handler.  */
    struct sigaction action;
    memset (&action, 0, sizeof action);

    action.sa_sigaction = signal_handler;
    action.sa_flags = SA_RESTART | SA_SIGINFO;
    sigemptyset (&action.sa_mask);

    sigaction (SIGPROF, &action, NULL);

    struct itimerval timer;

    /* Fire 500 times / second. */
    timer.it_interval.tv_sec  = 0;
    timer.it_interval.tv_usec = 2000;

    timer.it_value   .tv_sec  = 0;
    timer.it_value   .tv_usec = 2000;

    setitimer (ITIMER_PROF, &timer, NULL);

    printf ("%i\n", fib43());

    return 0;
}
_______________________________________________
Libunwind-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to