Example #1
0
KSCrashType kscrashsentry_installWithContext(KSCrash_SentryContext* context,
                                             KSCrashType crashTypes,
                                             void (*onCrash)(void))
{
    KSLOG_DEBUG("Installing handlers with context %p, crash types 0x%x.", context, crashTypes);
    g_context = context;
    kscrashsentry_clearContext(g_context);
    g_context->onCrash = onCrash;

    KSCrashType installed = 0;
    for(size_t i = 0; i < g_sentriesCount; i++)
    {
        CrashSentry* sentry = &g_sentries[i];
        if(sentry->crashType & crashTypes)
        {
            if(sentry->install == NULL || sentry->install(context))
            {
                installed |= sentry->crashType;
            }
        }
    }

    KSLOG_DEBUG("Installation complete. Installed types 0x%x.", installed);
    return installed;
}
void kscrashsentry_reportUserException(const char* name,
                                       const char* reason,
                                       const char* language,
                                       const char* lineOfCode,
                                       const char* stackTrace,
                                       bool terminateProgram)
{
    if(g_context == NULL)
    {
        KSLOG_WARN("User-reported exception sentry is not installed. Exception has not been recorded.");
    }
    else
    {
        kscrashsentry_beginHandlingCrash(g_context);

        KSLOG_DEBUG("Suspending all threads");
        kscrashsentry_suspendThreads();

        KSLOG_DEBUG("Fetching call stack.");
        int callstackCount = 100;
        uintptr_t callstack[callstackCount];
        callstackCount = backtrace((void**)callstack, callstackCount);
        if(callstackCount <= 0)
        {
            KSLOG_ERROR("backtrace() returned call stack length of %d", callstackCount);
            callstackCount = 0;
        }

        KSLOG_DEBUG("Filling out context.");
        g_context->crashType = KSCrashTypeUserReported;
        g_context->offendingThread = ksmach_thread_self();
        g_context->registersAreValid = false;
        g_context->crashReason = reason;
        g_context->stackTrace = callstack;
        g_context->stackTraceLength = callstackCount;
        g_context->userException.name = name;
        g_context->userException.language = language;
        g_context->userException.lineOfCode = lineOfCode;
        g_context->userException.customStackTrace = stackTrace;

        KSLOG_DEBUG("Calling main crash handler.");
        g_context->onCrash();

        if(terminateProgram)
        {
            kscrashsentry_uninstall(KSCrashTypeAll);
            kscrashsentry_resumeThreads();
            abort();
        }
        else
        {
            kscrashsentry_clearContext(g_context);
            kscrashsentry_resumeThreads();
        }
    }
}
Example #3
0
void kscrashsentry_beginHandlingCrash(KSCrash_SentryContext* context)
{
    kscrashsentry_clearContext(context);
    context->handlingCrash = true;
}