mirror of https://github.com/xzeldon/htop.git
Use libunwind for printing backtrace
This commit is contained in:
parent
29983ff83a
commit
29e1fcfa05
77
CRT.c
77
CRT.c
|
@ -21,14 +21,22 @@ in the source distribution for its full text.
|
||||||
#include "ProvideCurses.h"
|
#include "ProvideCurses.h"
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
#ifdef HAVE_EXECINFO_H
|
|
||||||
#include <execinfo.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(HAVE_MEMFD_CREATE)
|
#if !defined(NDEBUG) && defined(HAVE_MEMFD_CREATE)
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_LIBUNWIND)
|
||||||
|
# define PRINT_BACKTRACE
|
||||||
|
# define UNW_LOCAL_ONLY
|
||||||
|
# include <libunwind.h>
|
||||||
|
# if defined(HAVE_DLADDR)
|
||||||
|
# include <dlfcn.h>
|
||||||
|
# endif
|
||||||
|
#elif defined(HAVE_EXECINFO_H)
|
||||||
|
# define PRINT_BACKTRACE
|
||||||
|
# include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define ColorIndex(i,j) ((7-(i))*8+(j))
|
#define ColorIndex(i,j) ((7-(i))*8+(j))
|
||||||
|
|
||||||
|
@ -1008,6 +1016,59 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors = CRT_colorSchemes[colorScheme];
|
CRT_colors = CRT_colorSchemes[colorScheme];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PRINT_BACKTRACE
|
||||||
|
static void print_backtrace(void) {
|
||||||
|
#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_LIBUNWIND)
|
||||||
|
unw_context_t context;
|
||||||
|
unw_getcontext(&context);
|
||||||
|
|
||||||
|
unw_cursor_t cursor;
|
||||||
|
unw_init_local(&cursor, &context);
|
||||||
|
|
||||||
|
unsigned int item = 0;
|
||||||
|
|
||||||
|
while (unw_step(&cursor) > 0) {
|
||||||
|
unw_word_t pc;
|
||||||
|
unw_get_reg(&cursor, UNW_REG_IP, &pc);
|
||||||
|
if (pc == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
char symbolName[256] = "?";
|
||||||
|
unw_word_t offset = 0;
|
||||||
|
unw_get_proc_name(&cursor, symbolName, sizeof(symbolName), &offset);
|
||||||
|
|
||||||
|
unw_proc_info_t pip;
|
||||||
|
pip.unwind_info = NULL;
|
||||||
|
|
||||||
|
const char* fname = "?";
|
||||||
|
const void* ptr = 0;
|
||||||
|
if (unw_get_proc_info(&cursor, &pip) == 0) {
|
||||||
|
ptr = (const void*)(pip.start_ip + offset);
|
||||||
|
|
||||||
|
#ifdef HAVE_DLADDR
|
||||||
|
Dl_info dlinfo;
|
||||||
|
if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname && *dlinfo.dli_fname)
|
||||||
|
fname = dlinfo.dli_fname;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* frame = "";
|
||||||
|
if (unw_is_signal_frame(&cursor) > 0)
|
||||||
|
frame = "{signal frame}";
|
||||||
|
|
||||||
|
fprintf(stderr, "%2u: %#14lx %s (%s+%#lx) [%p]%s%s\n", item++, pc, fname, symbolName, offset, ptr, frame ? " " : "", frame);
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_EXECINFO_H)
|
||||||
|
void* backtraceArray[256];
|
||||||
|
|
||||||
|
size_t size = backtrace(backtraceArray, ARRAYSIZE(backtraceArray));
|
||||||
|
backtrace_symbols_fd(backtraceArray, size, STDERR_FILENO);
|
||||||
|
#else
|
||||||
|
#error No implementation for print_backtrace()!
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CRT_handleSIGSEGV(int signal) {
|
void CRT_handleSIGSEGV(int signal) {
|
||||||
CRT_done();
|
CRT_done();
|
||||||
|
|
||||||
|
@ -1022,7 +1083,7 @@ void CRT_handleSIGSEGV(int signal) {
|
||||||
" - Likely steps to reproduce (How did it happen?)\n"
|
" - Likely steps to reproduce (How did it happen?)\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef HAVE_EXECINFO_H
|
#ifdef PRINT_BACKTRACE
|
||||||
fprintf(stderr, " - Backtrace of the issue (see below)\n");
|
fprintf(stderr, " - Backtrace of the issue (see below)\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1048,16 +1109,14 @@ void CRT_handleSIGSEGV(int signal) {
|
||||||
Settings_write(CRT_crashSettings, true);
|
Settings_write(CRT_crashSettings, true);
|
||||||
fprintf(stderr, "\n\n");
|
fprintf(stderr, "\n\n");
|
||||||
|
|
||||||
#ifdef HAVE_EXECINFO_H
|
#ifdef PRINT_BACKTRACE
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Backtrace information:\n"
|
"Backtrace information:\n"
|
||||||
"----------------------\n"
|
"----------------------\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void* backtraceArray[256];
|
print_backtrace();
|
||||||
|
|
||||||
size_t size = backtrace(backtraceArray, ARRAYSIZE(backtraceArray));
|
|
||||||
backtrace_symbols_fd(backtraceArray, size, STDERR_FILENO);
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
"To make the above information more practical to work with, "
|
"To make the above information more practical to work with, "
|
||||||
|
|
36
configure.ac
36
configure.ac
|
@ -253,6 +253,7 @@ AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||||
|
|
||||||
AC_CHECK_FUNCS([ \
|
AC_CHECK_FUNCS([ \
|
||||||
clock_gettime \
|
clock_gettime \
|
||||||
|
dladdr \
|
||||||
faccessat \
|
faccessat \
|
||||||
fstatat \
|
fstatat \
|
||||||
host_get_clock_service \
|
host_get_clock_service \
|
||||||
|
@ -261,9 +262,6 @@ AC_CHECK_FUNCS([ \
|
||||||
readlinkat \
|
readlinkat \
|
||||||
])
|
])
|
||||||
|
|
||||||
# Add -lexecinfo if needed
|
|
||||||
AC_SEARCH_LIBS([backtrace], [execinfo])
|
|
||||||
|
|
||||||
if test "$my_htop_platform" = darwin; then
|
if test "$my_htop_platform" = darwin; then
|
||||||
AC_CHECK_FUNCS([mach_timebase_info])
|
AC_CHECK_FUNCS([mach_timebase_info])
|
||||||
fi
|
fi
|
||||||
|
@ -409,6 +407,36 @@ if test "x$enable_affinity" = xyes; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([unwind],
|
||||||
|
[AS_HELP_STRING([--enable-unwind],
|
||||||
|
[enable unwind support for printing backtraces; requires libunwind @<:@default=check@:>@])],
|
||||||
|
[],
|
||||||
|
[enable_unwind=check])
|
||||||
|
case "$enable_unwind" in
|
||||||
|
check)
|
||||||
|
enable_unwind=yes
|
||||||
|
if test "$enable_static" = yes; then
|
||||||
|
AC_CHECK_LIB([lzma], [lzma_index_buffer_decode])
|
||||||
|
fi
|
||||||
|
AC_CHECK_LIB([unwind], [backtrace], [], [enable_unwind=no])
|
||||||
|
AC_CHECK_HEADERS([libunwind.h], [], [enable_unwind=no])
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
;;
|
||||||
|
yes)
|
||||||
|
AC_CHECK_LIB([unwind], [backtrace], [], [AC_MSG_ERROR([can not find required library libunwind])])
|
||||||
|
AC_CHECK_HEADERS([libunwind.h], [], [AC_MSG_ERROR([can not find require header file libunwind.h])])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR([bad value '$enable_unwind' for --enable-unwind])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if test "x$enable_unwind" = xno; then
|
||||||
|
# Fall back to backtrace(3) and add -lexecinfo if needed
|
||||||
|
AC_SEARCH_LIBS([backtrace], [execinfo])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_ENABLE([hwloc],
|
AC_ARG_ENABLE([hwloc],
|
||||||
[AS_HELP_STRING([--enable-hwloc],
|
[AS_HELP_STRING([--enable-hwloc],
|
||||||
[enable hwloc support for CPU affinity; disables affinity support; requires libhwloc @<:@default=no@:>@])],
|
[enable hwloc support for CPU affinity; disables affinity support; requires libhwloc @<:@default=no@:>@])],
|
||||||
|
@ -426,6 +454,7 @@ case "$enable_hwloc" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_WITH([os-release],
|
AC_ARG_WITH([os-release],
|
||||||
[AS_HELP_STRING([--with-os-release=FILE],
|
[AS_HELP_STRING([--with-os-release=FILE],
|
||||||
[location of an os-release file @<:@default=/etc/os-release@:>@])],
|
[location of an os-release file @<:@default=/etc/os-release@:>@])],
|
||||||
|
@ -715,6 +744,7 @@ AC_MSG_RESULT([
|
||||||
(Linux) capabilities: $enable_capabilities
|
(Linux) capabilities: $enable_capabilities
|
||||||
unicode: $enable_unicode
|
unicode: $enable_unicode
|
||||||
affinity: $enable_affinity
|
affinity: $enable_affinity
|
||||||
|
unwind: $enable_unwind
|
||||||
hwloc: $enable_hwloc
|
hwloc: $enable_hwloc
|
||||||
debug: $enable_debug
|
debug: $enable_debug
|
||||||
static: $enable_static
|
static: $enable_static
|
||||||
|
|
Loading…
Reference in New Issue