Use easylogging++'s stack trace facility where possible

This avoids using libunwind, which often causes trouble.
This commit is contained in:
moneromooo-monero 2017-02-04 12:33:03 +00:00
parent b01990124e
commit cd34fc655d
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
3 changed files with 34 additions and 8 deletions

View file

@ -275,17 +275,23 @@ add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}")
# Can't install hook in static build on OSX, because OSX linker does not support --wrap # 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. # On ARM, having libunwind package (with .so's only) installed breaks static link.
if(APPLE OR (ARM AND STATIC)) 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(LIBUNWIND_LIBRARIES "")
elseif (ARM AND STATIC)
set(DEFAULT_STACK_TRACE OFF) set(DEFAULT_STACK_TRACE OFF)
set(LIBUNWIND_LIBRARIES "") set(LIBUNWIND_LIBRARIES "")
else() else()
find_package(Libunwind) find_package(Libunwind)
if(LIBUNWIND_FOUND) if(LIBUNWIND_FOUND)
set(DEFAULT_STACK_TRACE ON) set(DEFAULT_STACK_TRACE ON)
else() else()
set(DEFAULT_STACK_TRACE OFF) set(DEFAULT_STACK_TRACE OFF)
set(LIBUNWIND_LIBRARIES "") set(LIBUNWIND_LIBRARIES "")
endif() endif()
endif() endif()
option(STACK_TRACE "Install a hook that dumps stack on exception" ${DEFAULT_STACK_TRACE}) option(STACK_TRACE "Install a hook that dumps stack on exception" ${DEFAULT_STACK_TRACE})

View file

@ -51,8 +51,9 @@
#define ELPP_THREAD_SAFE #define ELPP_THREAD_SAFE
#define ELPP_DEFAULT_LOG_FILE "" #define ELPP_DEFAULT_LOG_FILE ""
#define ELPP_STACKTRACE 0 #define ELPP_STACKTRACE_ON_CRASH 0
#define ELPP_DISABLE_DEFAULT_CRASH_HANDLING #define ELPP_DISABLE_DEFAULT_CRASH_HANDLING
#define ELPP_FEATURE_CRASH_LOG 1
#define ELPP_DISABLE_CHECK_MACROS #define ELPP_DISABLE_CHECK_MACROS
#include "easylogging++.h" #include "easylogging++.h"

View file

@ -26,11 +26,17 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // 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. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__
#define USE_UNWIND
#endif
#include "common/stack_trace.h" #include "common/stack_trace.h"
#include "misc_log_ex.h" #include "misc_log_ex.h"
#ifdef USE_UNWIND
#define UNW_LOCAL_ONLY #define UNW_LOCAL_ONLY
#include <libunwind.h> #include <libunwind.h>
#include <cxxabi.h> #include <cxxabi.h>
#endif
#ifndef STATICLIB #ifndef STATICLIB
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
@ -99,6 +105,7 @@ void set_stack_trace_log(const std::string &log)
void log_stack_trace(const char *msg) void log_stack_trace(const char *msg)
{ {
#ifdef USE_UNWIND
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;
@ -106,10 +113,13 @@ void log_stack_trace(const char *msg)
char sym[512], *dsym; char sym[512], *dsym;
int status; int status;
const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str(); const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str();
#endif
if (msg) if (msg)
ST_LOG(msg); ST_LOG(msg);
ST_LOG("Unwound call stack:"); ST_LOG("Unwound call stack:");
#ifdef USE_UNWIND
if (unw_getcontext(&ctx) < 0) { if (unw_getcontext(&ctx) < 0) {
ST_LOG("Failed to create unwind context"); ST_LOG("Failed to create unwind context");
return; return;
@ -138,6 +148,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); ST_LOG(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off);
free(dsym); free(dsym);
} }
#else
std::stringstream ss;
ss << el::base::debug::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);
#endif
} }
} // namespace tools } // namespace tools