30 #if !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__
33 #define ELPP_FEATURE_CRASH_LOG 1
39 #define UNW_LOCAL_ONLY
40 #include <libunwind.h>
46 #include <boost/algorithm/string.hpp>
50 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
51 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "stacktrace"
57 CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,ELECTRONEUM_DEFAULT_LOG_CATEGORY) << x; \
60 std::cout << x << std::endl; \
69 #define CXA_THROW_INFO_T std::type_info
71 #define CXA_THROW_INFO_T void
75 #define CXA_THROW __wrap___cxa_throw
80 #define CXA_THROW __cxa_throw
95 char *dsym = abi::__cxa_demangle(((
const std::type_info*)
info)->
name(), NULL, NULL, &status);
118 stack_trace_log = log;
128 char sym[512], *dsym;
130 const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str();
135 ST_LOG(
"Unwound call stack:");
138 if (unw_getcontext(&ctx) < 0) {
139 ST_LOG(
"Failed to create unwind context");
142 if (unw_init_local(&cur, &ctx) < 0) {
143 ST_LOG(
"Failed to find the first unwind frame");
146 for (level = 1; level < 999; ++level) {
147 int ret = unw_step(&cur);
149 ST_LOG(
"Failed to find the next frame");
154 if (unw_get_reg(&cur, UNW_REG_IP, &
ip) < 0) {
155 ST_LOG(
" " << std::setw(4) << level);
158 if (unw_get_proc_name(&cur, sym,
sizeof(sym), &off) < 0) {
159 ST_LOG(
" " << std::setw(4) << level << std::setbase(16) << std::setw(20) <<
"0x" <<
ip);
162 dsym = abi::__cxa_demangle(sym, NULL, NULL, &status);
163 ST_LOG(
" " << std::setw(4) << level << std::setbase(16) << std::setw(20) <<
"0x" <<
ip <<
" " << (!status && dsym ? dsym : sym) <<
" + " <<
"0x" << off);
167 std::stringstream ss;
168 ss << el::base::debug::StackTrace();
169 std::vector<std::string> lines;
171 boost::split(lines, s, boost::is_any_of(
"\n"));
172 for (
const auto &line: lines)
boost::endian::big_uint32_t ip
__attribute__((noreturn)) void CXA_THROW(void *ex
CXA_THROW_INFO_T void(* dest)(void *))
void() cxa_throw_t(void *ex, CXA_THROW_INFO_T *info, void(*dest)(void *))