1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| static void CPPExceptionTerminate(void) { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; ksmc_suspendEnvironment(&threads, &numThreads); KSLOG_DEBUG("Trapped c++ exception"); const char* name = NULL; std::type_info* tinfo = __cxxabiv1::__cxa_current_exception_type(); if(tinfo != NULL) { name = tinfo->name(); } if(name == NULL || strcmp(name, "NSException") != 0) { kscm_notifyFatalExceptionCaptured(false); KSCrash_MonitorContext* crashContext = &g_monitorContext; memset(crashContext, 0, sizeof(*crashContext));
char descriptionBuff[DESCRIPTION_BUFFER_LENGTH]; const char* description = descriptionBuff; descriptionBuff[0] = 0;
KSLOG_DEBUG("Discovering what kind of exception was thrown."); g_captureNextStackTrace = false; try { throw; } catch(std::exception& exc) { strncpy(descriptionBuff, exc.what(), sizeof(descriptionBuff)); } #define CATCH_VALUE(TYPE, PRINTFTYPE) \ catch(TYPE value)\ { \ snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, value); \ } CATCH_VALUE(char, d) CATCH_VALUE(short, d) CATCH_VALUE(int, d) CATCH_VALUE(long, ld) CATCH_VALUE(long long, lld) CATCH_VALUE(unsigned char, u) CATCH_VALUE(unsigned short, u) CATCH_VALUE(unsigned int, u) CATCH_VALUE(unsigned long, lu) CATCH_VALUE(unsigned long long, llu) CATCH_VALUE(float, f) CATCH_VALUE(double, f) CATCH_VALUE(long double, Lf) CATCH_VALUE(char*, s) catch(...) { description = NULL; } g_captureNextStackTrace = g_isEnabled;
// TODO: Should this be done here? Maybe better in the exception handler? KSMC_NEW_CONTEXT(machineContext); ksmc_getContextForThread(ksthread_self(), machineContext, true);
KSLOG_DEBUG("Filling out context."); crashContext->crashType = KSCrashMonitorTypeCPPException; crashContext->eventID = g_eventID; crashContext->registersAreValid = false; crashContext->stackCursor = &g_stackCursor; crashContext->CPPException.name = name; crashContext->exceptionName = name; crashContext->crashReason = description; crashContext->offendingMachineContext = machineContext;
kscm_handleException(crashContext); } else { KSLOG_DEBUG("Detected NSException. Letting the current NSException handler deal with it."); } ksmc_resumeEnvironment(threads, numThreads);
KSLOG_DEBUG("Calling original terminate handler."); g_originalTerminateHandler(); }
|