backtrace: add an alternative stack unwinding implementation using libunwind
This commit is contained in:
parent
d8f6f0c01c
commit
83714577a9
|
@ -238,6 +238,7 @@ ARG_ENABL_SET([radattr], [enable plugin to inject and process custom RADI
|
||||||
ARG_ENABL_SET([vstr], [enforce using the Vstr string library to replace glibc-like printf hooks.])
|
ARG_ENABL_SET([vstr], [enforce using the Vstr string library to replace glibc-like printf hooks.])
|
||||||
ARG_ENABL_SET([monolithic], [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.])
|
ARG_ENABL_SET([monolithic], [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.])
|
||||||
ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.])
|
ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.])
|
||||||
|
ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.])
|
||||||
ARG_ENABL_SET([unit-tests], [enable unit tests using the check test framework.])
|
ARG_ENABL_SET([unit-tests], [enable unit tests using the check test framework.])
|
||||||
ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.])
|
ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.])
|
||||||
|
|
||||||
|
@ -886,6 +887,14 @@ if test x$bfd_backtraces = xtrue; then
|
||||||
AC_SUBST(BFDLIB)
|
AC_SUBST(BFDLIB)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$unwind_backtraces = xtrue; then
|
||||||
|
AC_CHECK_LIB([unwind],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([libunwind not found!])],[])
|
||||||
|
AC_CHECK_HEADER([libunwind.h],[AC_DEFINE([HAVE_LIBUNWIND_H],,[have libunwind.h])],
|
||||||
|
[AC_MSG_ERROR([libunwind.h header not found!])])
|
||||||
|
UNWINDLIB="-lunwind"
|
||||||
|
AC_SUBST(UNWINDLIB)
|
||||||
|
fi
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_DEV_HEADERS, [test "x$dev_headers" != xno])
|
AM_CONDITIONAL(USE_DEV_HEADERS, [test "x$dev_headers" != xno])
|
||||||
if test x$dev_headers = xyes; then
|
if test x$dev_headers = xyes; then
|
||||||
dev_headers="$includedir/strongswan"
|
dev_headers="$includedir/strongswan"
|
||||||
|
|
|
@ -79,7 +79,7 @@ endif
|
||||||
|
|
||||||
library.lo : $(top_builddir)/config.status
|
library.lo : $(top_builddir)/config.status
|
||||||
|
|
||||||
libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) $(BFDLIB)
|
libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) $(BFDLIB) $(UNWINDLIB)
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||||
AM_CFLAGS = \
|
AM_CFLAGS = \
|
||||||
|
|
|
@ -373,7 +373,7 @@ void backtrace_deinit() {}
|
||||||
METHOD(backtrace_t, log_, void,
|
METHOD(backtrace_t, log_, void,
|
||||||
private_backtrace_t *this, FILE *file, bool detailed)
|
private_backtrace_t *this, FILE *file, bool detailed)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_BACKTRACE
|
#if defined(HAVE_BACKTRACE) || defined(HAVE_LIBUNWIND_H)
|
||||||
size_t i;
|
size_t i;
|
||||||
char **strings;
|
char **strings;
|
||||||
|
|
||||||
|
@ -420,9 +420,9 @@ METHOD(backtrace_t, log_, void,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (strings);
|
free (strings);
|
||||||
#else /* !HAVE_BACKTRACE */
|
#else /* !HAVE_BACKTRACE && !HAVE_LIBUNWIND_H */
|
||||||
println(file, "C library does not support backtrace().");
|
println(file, "no support for backtrace()/libunwind");
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE/HAVE_LIBUNWIND_H */
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(backtrace_t, contains_function, bool,
|
METHOD(backtrace_t, contains_function, bool,
|
||||||
|
@ -518,6 +518,33 @@ METHOD(backtrace_t, destroy, void,
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUNWIND_H
|
||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* libunwind variant for glibc backtrace()
|
||||||
|
*/
|
||||||
|
static inline int backtrace_unwind(void **frames, int count)
|
||||||
|
{
|
||||||
|
unw_context_t context;
|
||||||
|
unw_cursor_t cursor;
|
||||||
|
unw_word_t ip;
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
|
unw_getcontext(&context);
|
||||||
|
unw_init_local(&cursor, &context);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||||
|
frames[depth++] = (void*)ip;
|
||||||
|
}
|
||||||
|
while (depth < count && unw_step(&cursor) > 0);
|
||||||
|
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_UNWIND */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
|
@ -527,7 +554,9 @@ backtrace_t *backtrace_create(int skip)
|
||||||
void *frames[50];
|
void *frames[50];
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_LIBUNWIND_H
|
||||||
|
frame_count = backtrace_unwind(frames, countof(frames));
|
||||||
|
#elif defined(HAVE_BACKTRACE)
|
||||||
frame_count = backtrace(frames, countof(frames));
|
frame_count = backtrace(frames, countof(frames));
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE */
|
||||||
frame_count = max(frame_count - skip, 0);
|
frame_count = max(frame_count - skip, 0);
|
||||||
|
|
Loading…
Reference in New Issue