cmake,common: flag for stack trace

By default the flag is enabled whenever libunwind is found on the
system, with the exception of static build on OSX (for which we can't
install the throw hook #932 due to lack of support for --wrap in OSX
ld64 linker).
This commit is contained in:
redfish 2016-07-27 01:02:55 -04:00
parent b34506da81
commit 0f990d0183
4 changed files with 35 additions and 25 deletions

View file

@ -249,14 +249,29 @@ endif()
add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}") add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}")
find_package(Libunwind) find_package(Libunwind)
if(LIBUNWIND_FOUND) # Can't install hook in static build on OSX, because OSX linker does not support --wrap
message(STATUS "Using libunwind to provide stack traces") if(LIBUNWIND_FOUND AND NOT (STATIC AND APPLE))
add_definitions("-DHAVE_LIBUNWIND") set(DEFAULT_STACK_TRACE ON)
else() else()
message(STATUS "Stack traces disabled") set(DEFAULT_STACK_TRACE OFF)
set(LIBUNWIND_LIBRARIES "") set(LIBUNWIND_LIBRARIES "")
endif() endif()
option(STACK_TRACE "Install a hook that dumps stack on exception" ${DEFAULT_STACK_TRACE})
if(STACK_TRACE)
message(STATUS "Stack trace on exception enabled")
# Don't set CMAKE_*_FLAGS directly or add_definitions, because this flag must
# not be set for tests targets (TODO: per-target logic into nested CMakeLists)
set(STACK_TRACE_C_FLAG "-DSTACK_TRACE")
if (STATIC)
set(STACK_TRACE_LINK_FLAG "-Wl,--wrap=__cxa_throw")
endif()
else()
message(STATUS "Stack trace on exception disabled")
endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
# Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail # Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
@ -424,11 +439,6 @@ else()
if(STATIC AND NOT APPLE AND NOT FREEBSD AND NOT OPENBSD) if(STATIC AND NOT APPLE AND NOT FREEBSD AND NOT OPENBSD)
set(COMMON_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") set(COMMON_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif() endif()
if(STATIC AND NOT FREEBSD AND NOT OPENBSD)
# Install hook on throw for dumping stack on exception (implemented in libcommon)
set(WRAP_CXA_THROW_FLAG "-Wl,--wrap=__cxa_throw")
endif()
endif() endif()
if (${BOOST_IGNORE_SYSTEM_PATHS} STREQUAL "ON") if (${BOOST_IGNORE_SYSTEM_PATHS} STREQUAL "ON")
@ -476,12 +486,10 @@ endif()
include(version.cmake) include(version.cmake)
# When building the following sources... # When building the following sources treat warnings as errors, install throw wrapper
# ...treat warnings as errors, install throw wrapper set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} ${WARNINGS_AS_ERRORS_FLAG} ${STACK_TRACE_C_FLAG}")
set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} ${WARNINGS_AS_ERRORS_FLAG}") set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS} ${WARNINGS_AS_ERRORS_FLAG} ${STACK_TRACE_C_FLAG}")
set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS} ${WARNINGS_AS_ERRORS_FLAG}") set(CMAKE_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} ${STACK_TRACE_LINK_FLAG}")
# ...install hook on throw
set(CMAKE_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} ${WRAP_CXA_THROW_FLAG}")
add_subdirectory(contrib) add_subdirectory(contrib)
add_subdirectory(src) add_subdirectory(src)
@ -490,11 +498,9 @@ add_subdirectory(src)
option(BUILD_TESTS "Build tests." OFF) option(BUILD_TESTS "Build tests." OFF)
if(BUILD_TESTS) if(BUILD_TESTS)
# When building tests... # When building tests, don't add some of the flags added to source build
# ...do *not* treat warnings as errors
set(CMAKE_C_FLAGS "${COMMON_C_FLAGS}") set(CMAKE_C_FLAGS "${COMMON_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS}")
# ...do *not* install hook on throw
set(CMAKE_EXE_LINKER_FLAGS "${COMMON_CXX_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${COMMON_CXX_FLAGS}")
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()

View file

@ -31,8 +31,11 @@ set(common_sources
command_line.cpp command_line.cpp
dns_utils.cpp dns_utils.cpp
util.cpp util.cpp
i18n.cpp i18n.cpp)
stack_trace.cpp)
if (STACK_TRACE)
list(APPEND common_sources stack_trace.cpp)
endif()
set(common_headers) set(common_headers)

View file

@ -28,10 +28,8 @@
#include "common/stack_trace.h" #include "common/stack_trace.h"
#include "misc_log_ex.h" #include "misc_log_ex.h"
#ifdef HAVE_LIBUNWIND
#define UNW_LOCAL_ONLY #define UNW_LOCAL_ONLY
#include <libunwind.h> #include <libunwind.h>
#endif
#include <cxxabi.h> #include <cxxabi.h>
#ifndef STATICLIB #ifndef STATICLIB
#include <dlfcn.h> #include <dlfcn.h>
@ -96,7 +94,6 @@ void set_stack_trace_log(const std::string &log)
void log_stack_trace(const char *msg) void log_stack_trace(const char *msg)
{ {
#ifdef HAVE_LIBUNWIND
unw_context_t ctx; unw_context_t ctx;
unw_cursor_t cur; unw_cursor_t cur;
unw_word_t ip, off; unw_word_t ip, off;
@ -136,7 +133,6 @@ void log_stack_trace(const char *msg)
LOG_PRINT2(log, " " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off, LOG_LEVEL_0); LOG_PRINT2(log, " " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off, LOG_LEVEL_0);
free(dsym); free(dsym);
} }
#endif
} }
} // namespace tools } // namespace tools

View file

@ -31,7 +31,6 @@
#include "common/command_line.h" #include "common/command_line.h"
#include "common/scoped_message_writer.h" #include "common/scoped_message_writer.h"
#include "common/util.h" #include "common/util.h"
#include "common/stack_trace.h"
#include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_core/miner.h" #include "cryptonote_core/miner.h"
#include "daemon/command_server.h" #include "daemon/command_server.h"
@ -44,6 +43,10 @@
#include "daemon/command_line_args.h" #include "daemon/command_line_args.h"
#include "blockchain_db/db_types.h" #include "blockchain_db/db_types.h"
#ifdef STACK_TRACE
#include "common/stack_trace.h"
#endif // STACK_TRACE
namespace po = boost::program_options; namespace po = boost::program_options;
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
@ -269,7 +272,9 @@ int main(int argc, char const * argv[])
, log_file_path.filename().string().c_str() , log_file_path.filename().string().c_str()
, log_file_path.parent_path().string().c_str() , log_file_path.parent_path().string().c_str()
); );
#ifdef STACK_TRACE
tools::set_stack_trace_log(log_file_path.filename().string()); tools::set_stack_trace_log(log_file_path.filename().string());
#endif // STACK_TRACE
} }
if (command_line::has_arg(vm, daemon_args::arg_max_concurrency)) if (command_line::has_arg(vm, daemon_args::arg_max_concurrency))