diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a0e75119..63d39ca75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,14 +249,29 @@ endif() add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}") find_package(Libunwind) -if(LIBUNWIND_FOUND) - message(STATUS "Using libunwind to provide stack traces") - add_definitions("-DHAVE_LIBUNWIND") +# Can't install hook in static build on OSX, because OSX linker does not support --wrap +if(LIBUNWIND_FOUND AND NOT (STATIC AND APPLE)) + set(DEFAULT_STACK_TRACE ON) else() - message(STATUS "Stack traces disabled") + set(DEFAULT_STACK_TRACE OFF) set(LIBUNWIND_LIBRARIES "") 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) # Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -424,11 +439,6 @@ else() if(STATIC AND NOT APPLE AND NOT FREEBSD AND NOT OPENBSD) set(COMMON_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") 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() if (${BOOST_IGNORE_SYSTEM_PATHS} STREQUAL "ON") @@ -476,12 +486,10 @@ endif() include(version.cmake) -# When building the following sources... -# ...treat warnings as errors, install throw wrapper -set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} ${WARNINGS_AS_ERRORS_FLAG}") -set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS} ${WARNINGS_AS_ERRORS_FLAG}") -# ...install hook on throw -set(CMAKE_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} ${WRAP_CXA_THROW_FLAG}") +# When building the following sources treat warnings as errors, install throw wrapper +set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} ${WARNINGS_AS_ERRORS_FLAG} ${STACK_TRACE_C_FLAG}") +set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS} ${WARNINGS_AS_ERRORS_FLAG} ${STACK_TRACE_C_FLAG}") +set(CMAKE_EXE_LINKER_FLAGS "${COMMON_EXE_LINKER_FLAGS} ${STACK_TRACE_LINK_FLAG}") add_subdirectory(contrib) add_subdirectory(src) @@ -490,11 +498,9 @@ add_subdirectory(src) option(BUILD_TESTS "Build tests." OFF) if(BUILD_TESTS) - # When building tests... - # ...do *not* treat warnings as errors + # When building tests, don't add some of the flags added to source build set(CMAKE_C_FLAGS "${COMMON_C_FLAGS}") set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS}") - # ...do *not* install hook on throw set(CMAKE_EXE_LINKER_FLAGS "${COMMON_CXX_FLAGS}") add_subdirectory(tests) endif() diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9afbe4b82..7a2457c93 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -31,8 +31,11 @@ set(common_sources command_line.cpp dns_utils.cpp util.cpp - i18n.cpp - stack_trace.cpp) + i18n.cpp) + +if (STACK_TRACE) + list(APPEND common_sources stack_trace.cpp) +endif() set(common_headers) diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index 44002e2d5..4387d4ffd 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -28,10 +28,8 @@ #include "common/stack_trace.h" #include "misc_log_ex.h" -#ifdef HAVE_LIBUNWIND #define UNW_LOCAL_ONLY #include -#endif #include #ifndef STATICLIB #include @@ -96,7 +94,6 @@ void set_stack_trace_log(const std::string &log) void log_stack_trace(const char *msg) { -#ifdef HAVE_LIBUNWIND unw_context_t ctx; unw_cursor_t cur; 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); free(dsym); } -#endif } } // namespace tools diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 638fae20e..2e8953af9 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -31,7 +31,6 @@ #include "common/command_line.h" #include "common/scoped_message_writer.h" #include "common/util.h" -#include "common/stack_trace.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/miner.h" #include "daemon/command_server.h" @@ -44,6 +43,10 @@ #include "daemon/command_line_args.h" #include "blockchain_db/db_types.h" +#ifdef STACK_TRACE +#include "common/stack_trace.h" +#endif // STACK_TRACE + namespace po = boost::program_options; 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.parent_path().string().c_str() ); +#ifdef STACK_TRACE tools::set_stack_trace_log(log_file_path.filename().string()); +#endif // STACK_TRACE } if (command_line::has_arg(vm, daemon_args::arg_max_concurrency))