/* Frame unwinder for frames using the libunwind library.
- Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc.
Written by Jeff Johnston, contributed by Red Hat Inc.
#include "complaints.h"
+/* The following two macros are normally defined in <endian.h>.
+ But systems such as ia64-hpux do not provide such header, so
+ we just define them here if not already defined. */
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+
static int libunwind_initialized;
static struct gdbarch_data *libunwind_descr_handle;
/* Allocate a new cache. */
cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
- /* We can assume we are unwinding a normal frame. Even if this is
- for a signal trampoline, ia64 signal "trampolines" use a normal
- subroutine call to start the signal handler. */
cache->func_addr = get_frame_func (this_frame);
- if (cache->func_addr == 0
- && get_next_frame (this_frame)
- && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME)
- return NULL;
+ if (cache->func_addr == 0)
+ /* This can happen when the frame corresponds to a function for which
+ there is no debugging information nor any entry in the symbol table.
+ This is probably a static function for which an entry in the symbol
+ table was not created when the objfile got linked (observed in
+ libpthread.so on ia64-hpux).
+
+ The best we can do, in that case, is use the frame PC as the function
+ address. We don't need to give up since we still have the unwind
+ record to help us perform the unwinding. There is also another
+ compelling to continue, because abandonning now means stopping
+ the backtrace, which can never be helpful for the user. */
+ cache->func_addr = get_frame_pc (this_frame);
/* Get a libunwind cursor to the previous frame.
static const struct frame_unwind libunwind_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
libunwind_frame_this_id,
libunwind_frame_prev_register,
NULL,
handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
if (handle == NULL)
- return 0;
+ {
+ fprintf_unfiltered (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
+ LIBUNWIND_SO, dlerror ());
+ return 0;
+ }
/* Initialize pointers to the dynamic library functions we will use. */