in AppCenterCrashes/AppCenterCrashes/Internals/MSACCrashesCXXExceptionHandler.mm [100:179]
static void MSACCrashesUncaughtCXXTerminateHandler(void) {
MSACCrashesUncaughtCXXExceptionInfo info = {
.exception = nullptr,
.exception_type_name = nullptr,
.exception_message = nullptr,
.exception_frames_count = 0,
.exception_frames = nullptr,
};
auto p = std::current_exception();
OSSpinLockLock(&_MSACCrashesCXXExceptionHandlingLock);
{
if (p) { // explicit operator bool
info.exception = reinterpret_cast<const void *>(&p);
info.exception_type_name = __cxxabiv1::__cxa_current_exception_type()->name();
MSACCrashesCXXExceptionTSInfo *recorded_info =
reinterpret_cast<MSACCrashesCXXExceptionTSInfo *>(pthread_getspecific(_MSACCrashesCXXExceptionInfoTSDKey));
if (recorded_info) {
info.exception_frames_count = recorded_info->num_frames - 1;
info.exception_frames = &recorded_info->call_stack[1];
} else {
// There's no backtrace, grab this function's trace instead. Probably means the exception came from a dynamically loaded library.
void *frames[128] = {nullptr};
info.exception_frames_count = static_cast<uint32_t>(backtrace(&frames[0], sizeof(frames) / sizeof(frames[0])) - 1);
info.exception_frames = reinterpret_cast<uintptr_t *>(&frames[1]);
}
try {
std::rethrow_exception(p);
} catch (const std::exception &e) {
// C++ exception.
info.exception_message = e.what();
MSACCrashesIterateExceptionHandlers_unlocked(info);
} catch (const std::exception *e) {
// C++ exception by pointer.
info.exception_message = e->what();
MSACCrashesIterateExceptionHandlers_unlocked(info);
} catch (const std::string &e) {
// C++ string as exception.
info.exception_message = e.c_str();
MSACCrashesIterateExceptionHandlers_unlocked(info);
} catch (const std::string *e) {
// C++ string pointer as exception.
info.exception_message = e->c_str();
MSACCrashesIterateExceptionHandlers_unlocked(info);
} catch (const char *e) { // Plain string as exception.
info.exception_message = e;
MSACCrashesIterateExceptionHandlers_unlocked(info);
} catch (__attribute__((unused)) id e) {
// Objective-C exception. Pass it on to Foundation.
OSSpinLockUnlock(&_MSACCrashesCXXExceptionHandlingLock);
if (_MSACCrashesOriginalTerminateHandler != nullptr) {
_MSACCrashesOriginalTerminateHandler();
}
return;
} catch (...) {
// Any other kind of exception. No message.
MSACCrashesIterateExceptionHandlers_unlocked(info);
}
}
}
OSSpinLockUnlock(&_MSACCrashesCXXExceptionHandlingLock);
// In case terminate is called reentrantly by passing it on.
if (_MSACCrashesOriginalTerminateHandler != nullptr) {
_MSACCrashesOriginalTerminateHandler();
} else {
abort();
}
}