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.
This commit is contained in:
UdjinM6 2020-12-01 07:18:46 +03:00 committed by GitHub
parent 3a02c6d74c
commit 548cdac180
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 4 deletions

View File

@ -34,6 +34,7 @@ endif()
add_definitions(
-DENABLE_CRASH_HOOKS=1
-DENABLE_STACKTRACES=1
-DENABLE_WALLET=1
)

View File

@ -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 <stdint.h>
# ensure backtrace() is found, check -lexecinfo if necessary
if test x$TARGET_OS != xwindows; then
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"

View File

@ -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

View File

@ -22,7 +22,9 @@
#include <windows.h>
#include <dbghelp.h>
#else
#ifdef ENABLE_STACKTRACES
#include <execinfo.h>
#endif
#include <unistd.h>
#include <signal.h>
#endif
@ -41,7 +43,10 @@
#include <mach/mach_vm.h>
#endif
#ifdef ENABLE_STACKTRACES
#include <backtrace.h>
#endif
#include <string.h>
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<uint64_t> 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<uint64_t> 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<uint64_t> GetStackFrames(size_t skip, size_t max_frames)
{
#ifdef ENABLE_STACKTRACES
// FYI, this is not using libbacktrace, but "backtrace()" from <execinfo.h>
std::vector<void*> buf(max_frames);
int count = backtrace(buf.data(), (int)buf.size());
@ -285,6 +297,9 @@ static __attribute__((noinline)) std::vector<uint64_t> 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<stackframe_info>*)data;
@ -346,6 +362,12 @@ static std::vector<stackframe_info> GetStackFrameInfos(const std::vector<uint64_
return infos;
}
#else
static std::vector<stackframe_info> GetStackFrameInfos(const std::vector<uint64_t>& stackframes)
{
return {};
}
#endif // ENABLE_STACKTRACES
struct crash_info_header
{