On 08/19/2011 04:53 PM, Ken Werner wrote:
On 08/19/2011 02:39 PM, Sven Neumann wrote:
Now I've updated libunwind to 1.0-rc1 and this trick doesn't seem to
work any longer. The code appears to crash in libunwind if used as
above. I had a look at the ARM implementation and found that there is
now code that's supposed to unw_step a signal handler. So I tried
without our hack and just use unw_getcontext(). Now it doesn't crash any
longer, but it also doesn't unwind over the signal handler. All I get is
a stack trace like this:
0x4016cde0 logUnwind() from /usr/lib/libraumfeld-1.0.so.0
0x40205654 ?? from /usr/lib/libunwind.so.7
Any ideas what we could do?
Hmm, this is interesting. How does your system look like (which libc,
kernel version) and are you stepping over RT or non-RT signal frames? It
would be helpful if you could share some code that shows the described
behavior.
In the meanwhile I'll prepare a simple testcase where I'll verify that
it's working on my system.
Attached is a simple testcase that works on my PandaBoard. How does it
look on your system? The output should look like this:
standard frame ip: 0x8988, sp: 0xbeffadd0 sig_handler
signal frame ip: 0x40113740, sp: 0xbefff2f0 __default_rt_sa_restorer_v2
standard frame ip: 0x8c4e, sp: 0xbefff660 main
standard frame ip: 0x40104623, sp: 0xbefff668 __libc_start_main
standard frame ip: 0x88b7, sp: 0xbefff7a8 _start
The ARMv7 board runs a Linaro evaluation build with a fairly recent
Linux kernel and glibc (www.linaro.org/downloads).
Regards
Ken
PS: I'll be on vacation for a few days starting tomorrow - bad timing.
But I'll follow the discussion afterwards.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
/*#define UNW_LOCAL_ONLY*/
#include <libunwind.h>
#define USE_TIMER
#define panic(args...) \
do { fprintf (stderr, args); exit (EXIT_FAILURE); } while (0)
static int loop = 1;
#ifdef USE_TIMER
static void sig_handler (int sig, siginfo_t *si, void *uc1)
#else
static void sig_handler (int sig)
#endif
{
unw_cursor_t cursor;
unw_context_t uc;
int ret;
loop = 0;
unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0)
panic ("unw_init_local() failed\n");
do
{
unw_word_t ip, sp, offp;
char buf[512];
unw_get_reg (&cursor, UNW_REG_IP, &ip);
unw_get_reg (&cursor, UNW_REG_SP, &sp);
unw_get_proc_name (&cursor, buf, sizeof (buf), &offp);
if (unw_is_signal_frame (&cursor))
printf ("signal frame\tip: %10p, sp: %10p %s\n", (void*) ip, (void*) sp, buf);
else
printf ("standard frame\tip: %10p, sp: %10p %s\n", (void*) ip, (void*) sp, buf);
}
while ((ret = unw_step (&cursor)) > 0);
if (ret < 0)
panic ("unw_step() failed\n");
}
#ifdef USE_TIMER
static void setup_timer (void)
{
struct sigaction act;
struct sigevent sev;
timer_t timerid;
struct itimerspec its;
memset (&its, 0, sizeof (its));
/* establish a handler for the timer signal */
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = sig_handler;
if (sigaction (SIGRTMIN, &act, NULL) == -1)
panic ("sigaction failed\n");
/* create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1)
panic ("timer_create\n");
/* start the timer */
its.it_value.tv_sec = 1; /* 1 second */
if (timer_settime(timerid, 0, &its, NULL) == -1)
panic ("timer_settime\n");
}
#endif
int
main ()
{
#ifdef USE_TIMER
setup_timer ();
while (loop);
#else
signal (SIGUSR1, sig_handler);
kill (getpid (), SIGUSR1);
#endif
return 0;
}
# only DWARF
#ARM_UNW_METHOD = 1
# only ARM specific unwind tables
#ARM_UNW_METHOD = 4
# both
ARM_UNW_METHOD = 255
CFLAGS = -I../../include -funwind-tables -g -O0
LDFLAGS = -L../../src/.libs/ -lunwind -lunwind-arm -lrt
WARNINGS = -Wall -Wextra -Winline
BIN = main
SRC = main.c
OBJ = $(SRC:%.c=%.o)
all: $(SRC) $(BIN)
$(BIN): $(OBJ) $(LIB1_SO)
$(CC) $(CFLAGS) $(WARNINGS) $(OBJ) -o $(BIN) $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) $(WARNINGS) -c $< -o $@
clean:
rm -f $(BIN) $(OBJ)
run: all
UNW_ARM_UNWIND_METHOD=$(ARM_UNW_METHOD) LD_LIBRARY_PATH=../../src/.libs
./$(BIN)
gdb: all
UNW_ARM_UNWIND_METHOD=$(ARM_UNW_METHOD) LD_LIBRARY_PATH=../../src/.libs
gdb --args ./$(BIN)
.PHONY: clean run gdb
_______________________________________________
Libunwind-devel mailing list
Libunwind-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/libunwind-devel