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

Reply via email to