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 83 #ifdef __clang__ // only clang, not GCC, lets apply the attr in typedef 95 char *dsym = abi::__cxa_demangle(((
const std::type_info*)
info)->
name(), NULL, NULL, &status);
100 #ifndef __clang__ // for GCC the attr can't be applied in typedef like for clang 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)
CXA_THROW_INFO_T void(* dest)(void *))
void() cxa_throw_t(void *ex, CXA_THROW_INFO_T *info, void(*dest)(void *))
boost::endian::big_uint32_t ip
__attribute__((noreturn)) void CXA_THROW(void *ex