aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-04-14 10:49:17 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-04-15 14:47:00 +0100
commitef35cb23539ac1984373ad5e6775c7fd26d6f948 (patch)
treea47b1c3259ed15ff56a63fc2db37c93f3daa37d9
parentd8584fc8d78f1e97dfef214416d826b9f764c2e0 (diff)
downloadmonzero-core-crash-pl.tar.gz
monzero-core-crash-pl.tar.xz
monzero-core-crash-pl.zip
optional boost stacktrace to get stack traces on mac and windows toocrash-pl
Thanks to iDunk for lots of testing to get this to work on Windows
-rw-r--r--CMakeLists.txt98
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/stack_trace.cpp27
4 files changed, 91 insertions, 48 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 08b47eaf6..3777b335d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -351,38 +351,6 @@ endif()
add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}")
-# Can't install hook in static build on OSX, because OSX linker does not support --wrap
-# On ARM, having libunwind package (with .so's only) installed breaks static link.
-# When possible, avoid stack tracing using libunwind in favor of using easylogging++.
-if (APPLE)
- set(DEFAULT_STACK_TRACE OFF)
- set(LIBUNWIND_LIBRARIES "")
-elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
- set(DEFAULT_STACK_TRACE ON)
- set(STACK_TRACE_LIB "easylogging++") # for diag output only
- set(LIBUNWIND_LIBRARIES "")
-elseif (ARM AND STATIC)
- set(DEFAULT_STACK_TRACE OFF)
- set(LIBUNWIND_LIBRARIES "")
-else()
- find_package(Libunwind)
- if(LIBUNWIND_FOUND)
- set(DEFAULT_STACK_TRACE ON)
- set(STACK_TRACE_LIB "libunwind") # for diag output only
- else()
- set(DEFAULT_STACK_TRACE OFF)
- 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 (using ${STACK_TRACE_LIB})")
-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)
@@ -798,6 +766,72 @@ elseif(Boost_FOUND)
endif()
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
+
+if (NOT Boost_VERSION VERSION_LESS 106500)
+if(MINGW)
+ check_library_exists(backtrace backtrace_full "backtrace.h" USE_BOOST_STACKTRACE)
+else()
+ set(USE_BOOST_STACKTRACE ON)
+endif()
+endif()
+
+# Can't install hook in static build on OSX, because OSX linker does not support --wrap
+# On ARM, having libunwind package (with .so's only) installed breaks static link.
+# When possible, avoid stack tracing using libunwind in favor of using easylogging++.
+if (NOT Boost_VERSION VERSION_LESS 106500 AND USE_BOOST_STACKTRACE)
+ set(DEFAULT_STACK_TRACE ON)
+ if (MINGW)
+ set(STACK_TRACE_LIBRARIES "-lbacktrace")
+ set(STACK_TRACE_LIB "boost/backtrace") # for diag output only
+ add_definitions(-DBOOST_STACKTRACE_USE_BACKTRACE)
+ else()
+ set(STACK_TRACE_LIBRARIES "")
+ set(STACK_TRACE_LIB "boost/addr2line") # for diag output only
+ add_definitions(-DBOOST_STACKTRACE_USE_ADDR2LINE)
+ endif()
+ add_definitions(-DUSE_BOOST_STACKTRACE)
+elseif (APPLE)
+ set(DEFAULT_STACK_TRACE OFF)
+ set(STACK_TRACE_LIBRARIES "")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
+ set(DEFAULT_STACK_TRACE ON)
+ set(STACK_TRACE_LIB "easylogging++") # for diag output only
+ set(STACK_TRACE_LIBRARIES "")
+ add_definitions(-DUSE_EASYLOGGING_STACKTRACE)
+elseif (ARM AND STATIC)
+ set(DEFAULT_STACK_TRACE OFF)
+ set(STACK_TRACE_LIBRARIES "")
+else()
+ find_package(Libunwind)
+ if(LIBUNWIND_FOUND)
+ set(DEFAULT_STACK_TRACE ON)
+ set(STACK_TRACE_LIBRARIES ${LIBUNWIND_LIBRARIES})
+ set(STACK_TRACE_LIB "libunwind") # for diag output only
+ add_definitions(-DUSE_LIBUNWIND_STACKTRACE)
+ else()
+ set(DEFAULT_STACK_TRACE OFF)
+ set(STACK_TRACE_LIBRARIES "")
+ endif()
+endif()
+
+option(STACK_TRACE "Enable stack trace dumping" ${DEFAULT_STACK_TRACE})
+option(STACK_TRACE_ON_EXCEPTIONS "Install a hook that dumps stack on exception" ${DEFAULT_STACK_TRACE})
+
+if(STACK_TRACE)
+ message(STATUS "Stack traces enabled (using ${STACK_TRACE_LIB})")
+ add_definitions(-DSTACK_TRACE)
+else()
+ message(STATUS "Stack traces disabled")
+endif()
+
+if(STACK_TRACE_ON_EXCEPTIONS)
+ message(STATUS "Stack trace on exception enabled")
+ add_definitions(-DSTACK_TRACE_ON_EXCEPTIONS)
+else()
+ message(STATUS "Stack trace on exception disabled")
+endif()
+
+
if(MINGW)
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi)
set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} icuio icuin icuuc icudt icutu iconv)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3b71c38cd..4cbdf1510 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -53,14 +53,10 @@ function (monero_install_headers subdir)
endfunction ()
function (enable_stack_trace target)
- if(STACK_TRACE)
- set_property(TARGET ${target}
- APPEND PROPERTY COMPILE_DEFINITIONS "STACK_TRACE")
- if (STATIC)
- set_property(TARGET "${target}"
- APPEND PROPERTY LINK_FLAGS "-Wl,--wrap=__cxa_throw")
- endif()
- endif()
+ if (STATIC AND STACK_TRACE_ON_EXCEPTIONS)
+ set_property(TARGET "${target}"
+ APPEND PROPERTY LINK_FLAGS "-Wl,--wrap=__cxa_throw")
+ endif()
endfunction()
function (monero_add_executable name)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 66fd8d7ad..02843b672 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -81,7 +81,7 @@ target_link_libraries(common
epee
cncrypto
${UNBOUND_LIBRARY}
- ${LIBUNWIND_LIBRARIES}
+ ${STACK_TRACE_LIBRARIES}
${Boost_DATE_TIME_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp
index 9c2bf4b53..1e762bf54 100644
--- a/src/common/stack_trace.cpp
+++ b/src/common/stack_trace.cpp
@@ -26,18 +26,19 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#if !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__
-#define USE_UNWIND
-#else
+#ifdef USE_BOOST_STACKTRACE
+#include <boost/stacktrace.hpp>
+#elif defined USE_EASYLOGGING_STACKTRACE
#define ELPP_FEATURE_CRASH_LOG 1
#endif
#include "easylogging++/easylogging++.h"
#include <stdexcept>
-#ifdef USE_UNWIND
+#ifdef USE_LIBUNWIND_STACKTRACE
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <cxxabi.h>
+#include <iomanip>
#endif
#ifndef STATICLIB
#include <dlfcn.h>
@@ -51,6 +52,8 @@
#define ST_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x
+#ifdef STACK_TRACE_ON_EXCEPTIONS
+
// from http://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c
// The decl of __cxa_throw in /usr/include/.../cxxabi.h uses
@@ -95,6 +98,8 @@ void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*))
__real___cxa_throw(ex, info, dest);
}
+#endif
+
namespace
{
std::string stack_trace_log;
@@ -110,7 +115,7 @@ void set_stack_trace_log(const std::string &log)
void log_stack_trace(const char *msg)
{
-#ifdef USE_UNWIND
+#ifdef USE_LIBUNWIND_STACKTRACE
unw_context_t ctx;
unw_cursor_t cur;
unw_word_t ip, off;
@@ -124,7 +129,7 @@ void log_stack_trace(const char *msg)
ST_LOG(msg);
ST_LOG("Unwound call stack:");
-#ifdef USE_UNWIND
+#ifdef USE_LIBUNWIND_STACKTRACE
if (unw_getcontext(&ctx) < 0) {
ST_LOG("Failed to create unwind context");
return;
@@ -153,7 +158,15 @@ void log_stack_trace(const char *msg)
ST_LOG(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off);
free(dsym);
}
-#else
+#elif defined USE_BOOST_STACKTRACE
+ std::stringstream ss;
+ ss << boost::stacktrace::stacktrace();
+ std::vector<std::string> lines;
+ std::string s = ss.str();
+ boost::split(lines, s, boost::is_any_of("\n"));
+ for (const auto &line: lines)
+ ST_LOG(line);
+#elif defined USE_EASYLOGGING_STACKTRACE
std::stringstream ss;
ss << el::base::debug::StackTrace();
std::vector<std::string> lines;