void __wrap___cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)) { static TlsBool is_currently_throwing; // if we throw during the course of executing stack save code // then we just abort if (is_currently_throwing) abort(); is_currently_throwing = true; // NB: by using __builtin_frame_address() we force this function to have a // frame pointer _dummy = __builtin_frame_address(0); // get stack trace void *frames[256]; auto frames_captured = CaptureStackBackTrace(1, safe::numelementsf(frames), frames, nullptr); auto stack_trace = std::vector<void *>(&frames[0], &frames[frames_captured]); safe::_set_backtrace_for_exception_ptr(thrown_exception, std::move(stack_trace)); is_currently_throwing = false; // call original __cxa_throw __real___cxa_throw(thrown_exception, tinfo, dest); }
void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)) { int status; char *dsym = abi::__cxa_demangle(((const std::type_info*)info)->name(), NULL, NULL, &status); tools::log_stack_trace((std::string("Exception: ")+((!status && dsym) ? dsym : (const char*)info)).c_str()); free(dsym); #ifndef STATICLIB #ifndef __clang__ // for GCC the attr can't be applied in typedef like for clang __attribute__((noreturn)) #endif // !__clang__ cxa_throw_t *__real___cxa_throw = (cxa_throw_t*)dlsym(RTLD_NEXT, "__cxa_throw"); #endif // !STATICLIB __real___cxa_throw(ex, info, dest); }