static void MSACCrashesUncaughtCXXTerminateHandler()

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();
  }
}