From 548cdac1801653dad76ca912d0f2ea67c4c2f72d Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 1 Dec 2020 07:18:46 +0300 Subject: [PATCH] Bring `--enable-stacktraces` configure option back (#3826) Make it possible to disable stacktraces completely again. This is needed for OSes with no backtrace support e.g. Alpine Linux. --- CMakeLists.txt | 1 + configure.ac | 30 ++++++++++++++++++++++++++---- src/Makefile.am | 2 ++ src/stacktraces.cpp | 22 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 670d3e3391..7691fe025f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ endif() add_definitions( -DENABLE_CRASH_HOOKS=1 + -DENABLE_STACKTRACES=1 -DENABLE_WALLET=1 ) diff --git a/configure.ac b/configure.ac index 1a0f0f0aef..1558558f07 100644 --- a/configure.ac +++ b/configure.ac @@ -220,6 +220,13 @@ AC_ARG_ENABLE([debug], [enable_debug=$enableval], [enable_debug=no]) +# Enable exception stacktraces +AC_ARG_ENABLE([stacktraces], + [AS_HELP_STRING([--enable-stacktraces], + [gather and print exception stack traces (default is yes)])], + [enable_stacktraces=$enableval], + [enable_stacktraces=yes]) + # Enable crash hooks AC_ARG_ENABLE([crash-hooks], [AS_HELP_STRING([--enable-crash-hooks], @@ -283,10 +290,22 @@ else fi fi +if test "x$enable_stacktraces" != xno; then + AC_CHECK_HEADERS([execinfo.h], [], [enable_stacktraces=no]) +fi + +AM_CONDITIONAL([ENABLE_STACKTRACES], [test x$enable_stacktraces = xyes]) +if test "x$enable_stacktraces" = xyes; then + AC_DEFINE(ENABLE_STACKTRACES, 1, [Define this symbol if stacktraces should be enabled]) +else + enable_crashhooks=no +fi + AM_CONDITIONAL([ENABLE_CRASH_HOOKS], [test x$enable_crashhooks = xyes]) if test "x$enable_crashhooks" = xyes; then AC_DEFINE(ENABLE_CRASH_HOOKS, 1, [Define this symbol if crash hooks should be enabled]) fi + AX_CHECK_LINK_FLAG([-Wl,-wrap=__cxa_allocate_exception], [LINK_WRAP_SUPPORTED=yes],,,) AM_CONDITIONAL([CRASH_HOOKS_WRAPPED_CXX_ABI],[test x$LINK_WRAP_SUPPORTED = xyes]) @@ -759,7 +778,7 @@ if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) fi -AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h execinfo.h]) +AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) AC_CHECK_DECLS([strnlen]) @@ -895,9 +914,11 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include # ensure backtrace() is found, check -lexecinfo if necessary if test x$TARGET_OS != xwindows; then - AC_SEARCH_LIBS([backtrace], [execinfo], [], [ - AC_MSG_ERROR([Unable to find backtrace()]) - ]) + if test "x$enable_stacktraces" != xno; then + AC_SEARCH_LIBS([backtrace], [execinfo], [], [ + AC_MSG_ERROR([Unable to find backtrace()]) + ]) + fi fi # Check for reduced exports @@ -1536,6 +1557,7 @@ echo " with upnp = $use_upnp" echo " use asm = $use_asm" echo " sanitizers = $use_sanitizers" echo " debug enabled = $enable_debug" +echo " stacktraces enabled = $enable_stacktraces" echo " crash hooks enabled = $enable_crashhooks" echo " miner enabled = $enable_miner" echo " gprof enabled = $enable_gprof" diff --git a/src/Makefile.am b/src/Makefile.am index 813a97cf83..2b6f64d1d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS = $(HARDENED_CPPFLAGS) AM_LIBTOOLFLAGS = --preserve-dup-deps EXTRA_LIBRARIES = +if ENABLE_STACKTRACES if ENABLE_CRASH_HOOKS if CRASH_HOOKS_WRAPPED_CXX_ABI # Wrap internal C++ ABI's so that we can attach stacktraces to exceptions @@ -28,6 +29,7 @@ BACKTRACE_LIB = -ldbghelp -lbacktrace else BACKTRACE_LIB = -lbacktrace endif +endif #ENABLE_STACKTRACES if EMBEDDED_UNIVALUE LIBUNIVALUE = univalue/libunivalue.la diff --git a/src/stacktraces.cpp b/src/stacktraces.cpp index 4b8e511585..ad233a1680 100644 --- a/src/stacktraces.cpp +++ b/src/stacktraces.cpp @@ -22,7 +22,9 @@ #include #include #else +#ifdef ENABLE_STACKTRACES #include +#endif #include #include #endif @@ -41,7 +43,10 @@ #include #endif +#ifdef ENABLE_STACKTRACES #include +#endif + #include std::string DemangleSymbol(const std::string& name) @@ -113,6 +118,7 @@ static std::string GetExeFileName() static std::string g_exeFileName = GetExeFileName(); static std::string g_exeFileBaseName = fs::path(g_exeFileName).filename().string(); +#ifdef ENABLE_STACKTRACES static void my_backtrace_error_callback (void *data, const char *msg, int errnum) { @@ -131,6 +137,7 @@ static backtrace_state* GetLibBacktraceState() static backtrace_state* st = backtrace_create_state(exeFileNamePtr, 1, my_backtrace_error_callback, nullptr); return st; } +#endif // ENABLE_STACKTRACES #if WIN32 static uint64_t GetBaseAddress() @@ -156,6 +163,7 @@ static uint64_t ConvertAddress(uint64_t addr) static __attribute__((noinline)) std::vector GetStackFrames(size_t skip, size_t max_frames, const CONTEXT* pContext = nullptr) { +#ifdef ENABLE_STACKTRACES // We can't use libbacktrace for stack unwinding on Windows as it returns invalid addresses (like 0x1 or 0xffffffff) static BOOL symInitialized = SymInitialize(GetCurrentProcess(), nullptr, TRUE); @@ -225,6 +233,9 @@ static __attribute__((noinline)) std::vector GetStackFrames(size_t ski } return ret; +#else + return {}; +#endif // ENABLE_STACKTRACES } #else @@ -271,6 +282,7 @@ static uint64_t GetBaseAddress() static __attribute__((noinline)) std::vector GetStackFrames(size_t skip, size_t max_frames) { +#ifdef ENABLE_STACKTRACES // FYI, this is not using libbacktrace, but "backtrace()" from std::vector buf(max_frames); int count = backtrace(buf.data(), (int)buf.size()); @@ -285,6 +297,9 @@ static __attribute__((noinline)) std::vector GetStackFrames(size_t ski ret.emplace_back((uint64_t) buf[i]); } return ret; +#else + return {}; +#endif // ENABLE_STACKTRACES } #endif @@ -306,6 +321,7 @@ struct stackframe_info { } }; +#ifdef ENABLE_STACKTRACES static int my_backtrace_full_callback (void *data, uintptr_t pc, const char *filename, int lineno, const char *function) { auto sis = (std::vector*)data; @@ -346,6 +362,12 @@ static std::vector GetStackFrameInfos(const std::vector GetStackFrameInfos(const std::vector& stackframes) +{ + return {}; +} +#endif // ENABLE_STACKTRACES struct crash_info_header {