示例#1
0
void kscrash_setDoNotIntrospectClasses(const char** doNotIntrospectClasses, size_t length)
{
    const char** oldClasses = crashContext()->config.introspectionRules.restrictedClasses;
    size_t oldClassesLength = crashContext()->config.introspectionRules.restrictedClassesCount;
    const char** newClasses = nil;
    size_t newClassesLength = 0;
    
    if(doNotIntrospectClasses != nil && length > 0)
    {
        newClassesLength = length;
        newClasses = malloc(sizeof(*newClasses) * newClassesLength);
        if(newClasses == nil)
        {
            KSLOG_ERROR("Could not allocate memory");
            return;
        }
        
        for(size_t i = 0; i < newClassesLength; i++)
        {
            newClasses[i] = strdup(doNotIntrospectClasses[i]);
        }
    }

    crashContext()->config.introspectionRules.restrictedClasses = newClasses;
    crashContext()->config.introspectionRules.restrictedClassesCount = newClassesLength;

    if(oldClasses != nil)
    {
        for(size_t i = 0; i < oldClassesLength; i++)
        {
            free((void*)oldClasses[i]);
        }
        free(oldClasses);
    }
}
示例#2
0
KSCrashType kscrash_setHandlingCrashTypes(KSCrashType crashTypes)
{
    if((crashTypes & KSCrashTypeDebuggerUnsafe) && ksmach_isBeingTraced())
    {
        KSLOGBASIC_WARN("KSCrash: App is running in a debugger. The following crash types have been disabled:");
        KSCrashType disabledCrashTypes = crashTypes & KSCrashTypeDebuggerUnsafe;
        for(int i = 0; i < 31; i++)
        {
            KSCrashType type = 1 << i;
            if(disabledCrashTypes & type)
            {
                KSLOGBASIC_WARN("* %s", kscrashtype_name(type));
            }
        }

        crashTypes &= KSCrashTypeDebuggerSafe;
    }

    KSCrash_Context* context = crashContext();
    context->config.handlingCrashTypes = crashTypes;

    if(g_installed)
    {
        kscrashsentry_uninstall(~crashTypes);
        crashTypes = kscrashsentry_installWithContext(&context->crash, crashTypes, kscrash_i_onCrash);
    }
    return crashTypes;
}
示例#3
0
KSCrashType kscrash_install(const char* const crashReportFilePath,
                            const char* const recrashReportFilePath,
                            const char* stateFilePath,
                            const char* crashID)
{
    KSLOG_DEBUG("Installing crash reporter.");

    KSCrash_Context* context = crashContext();

    if(g_installed)
    {
        KSLOG_DEBUG("Crash reporter already installed.");
        return context->config.handlingCrashTypes;
    }
    g_installed = 1;

    ksmach_init();
    ksobjc_init();

    kscrash_reinstall(crashReportFilePath,
                      recrashReportFilePath,
                      stateFilePath,
                      crashID);


    KSCrashType crashTypes = kscrash_setHandlingCrashTypes(context->config.handlingCrashTypes);

    context->config.systemInfoJSON = kssysteminfo_toJSON();
    context->config.processName = kssysteminfo_copyProcessName();

    KSLOG_DEBUG("Installation complete.");
    return crashTypes;
}
示例#4
0
KSCrashType kscrash_setHandlingCrashTypes(KSCrashType crashTypes)
{
    KSCrash_Context* context = crashContext();
    context->config.handlingCrashTypes = crashTypes;
    
    if(g_installed)
    {
        kscrashsentry_uninstall(~crashTypes);
        crashTypes = kscrashsentry_installWithContext(&context->crash, crashTypes, kscrash_i_onCrash);
    }

    return crashTypes;
}
示例#5
0
void kscrash_setUserInfoJSON(const char* const userInfoJSON)
{
    KSLOG_TRACE("set userInfoJSON to %p", userInfoJSON);
    KSCrash_Context* context = crashContext();
    if(context->config.userInfoJSON != NULL)
    {
        KSLOG_TRACE("Free old data at %p", context->config.userInfoJSON);
        free((void*)context->config.userInfoJSON);
    }
    if(userInfoJSON != NULL)
    {
        context->config.userInfoJSON = strdup(userInfoJSON);
        KSLOG_TRACE("Duplicated string to %p", context->config.userInfoJSON);
    }
}
示例#6
0
/** Called when a crash occurs.
 *
 * This function gets passed as a callback to a crash handler.
 */
void kscrash_i_onCrash(void)
{
    KSLOG_DEBUG("Updating application state to note crash.");
    kscrashstate_notifyAppCrash();

    KSCrash_Context* context = crashContext();

    if(context->config.printTraceToStdout)
    {
        kscrashreport_logCrash(context);
    }

    if(context->crash.crashedDuringCrashHandling)
    {
        kscrashreport_writeMinimalReport(context, g_recrashReportFilePath);
    }
    else
    {
        kscrashreport_writeStandardReport(context, g_crashReportFilePath);
    }
}
示例#7
0
void kscrash_reinstall(const char* const crashReportFilePath,
                       const char* const recrashReportFilePath,
                       const char* const stateFilePath,
                       const char* const crashID)
{
    KSLOG_TRACE("reportFilePath = %s", crashReportFilePath);
    KSLOG_TRACE("secondaryReportFilePath = %s", recrashReportFilePath);
    KSLOG_TRACE("stateFilePath = %s", stateFilePath);
    KSLOG_TRACE("crashID = %s", crashID);

    ksstring_replace((const char**)&g_stateFilePath, stateFilePath);
    ksstring_replace((const char**)&g_crashReportFilePath, crashReportFilePath);
    ksstring_replace((const char**)&g_recrashReportFilePath, recrashReportFilePath);
    KSCrash_Context* context = crashContext();
    ksstring_replace(&context->config.crashID, crashID);

    if(!kscrashstate_init(g_stateFilePath, &context->state))
    {
        KSLOG_ERROR("Failed to initialize persistent crash state");
    }
    context->state.appLaunchTime = mach_absolute_time();
}
示例#8
0
void kscrash_setCrashNotifyCallback(const KSReportWriteCallback onCrashNotify)
{
    KSLOG_TRACE("Set onCrashNotify to %p", onCrashNotify);
    crashContext()->config.onCrashNotify = onCrashNotify;
}
示例#9
0
void kscrash_setReportWhenDebuggerIsAttached(bool reportWhenDebuggerIsAttached)
{
    crashContext()->crash.reportWhenDebuggerIsAttached = reportWhenDebuggerIsAttached;
}
示例#10
0
void kscrash_setSuspendThreadsForUserReported(bool suspendThreadsForUserReported)
{
    crashContext()->crash.suspendThreadsForUserReported = suspendThreadsForUserReported;
}
示例#11
0
void kscrash_setIntrospectMemory(bool introspectMemory)
{
    crashContext()->config.introspectionRules.enabled = introspectMemory;
}
示例#12
0
void kscrash_setSearchQueueNames(bool shouldSearchQueueNames)
{
    crashContext()->config.searchQueueNames = shouldSearchQueueNames;
}
示例#13
0
void kscrash_setPrintTraceToStdout(bool printTraceToStdout)
{
    crashContext()->config.printTraceToStdout = printTraceToStdout;
}
示例#14
0
void kscrash_setUserInfoJSON(const char* const userInfoJSON)
{
    KSLOG_TRACE("set userInfoJSON to %p", userInfoJSON);
    KSCrash_Context* context = crashContext();
    ksstring_replace(&context->config.userInfoJSON, userInfoJSON);
}
示例#15
0
bool kscrash_install(const char* const crashReportFilePath,
                     const char* const recrashReportFilePath,
                     const char* const stateFilePath,
                     const char* const crashID,
                     const char* const userInfoJSON,
                     unsigned int zombieCacheSize,
                     const bool printTraceToStdout,
                     const KSReportWriteCallback onCrashNotify)
{
    KSLOG_DEBUG("Installing crash reporter.");
    KSLOG_TRACE("reportFilePath = %s", reportFilePath);
    KSLOG_TRACE("secondaryReportFilePath = %s", secondaryReportFilePath);
    KSLOG_TRACE("stateFilePath = %s", stateFilePath);
    KSLOG_TRACE("crashID = %s", crashID);
    KSLOG_TRACE("userInfoJSON = %p", userInfoJSON);
    KSLOG_TRACE("zombieCacheSize = %d", zombieCacheSize);
    KSLOG_TRACE("printTraceToStdout = %d", printTraceToStdout);
    KSLOG_TRACE("onCrashNotify = %p", onCrashNotify);

    static volatile sig_atomic_t initialized = 0;
    if(!initialized)
    {
        initialized = 1;

        g_stateFilePath = strdup(stateFilePath);
        g_crashReportFilePath = strdup(crashReportFilePath);
        g_recrashReportFilePath = strdup(recrashReportFilePath);
        KSCrash_Context* context = crashContext();
        context->crash.onCrash = kscrash_i_onCrash;

        if(ksmach_isBeingTraced())
        {
            KSLOGBASIC_WARN("KSCrash: App is running in a debugger. Crash handlers have been disabled for the sanity of all.");
        }
        else if(kscrashsentry_installWithContext(&context->crash,
                                                 KSCrashTypeAll) == 0)
        {
            KSLOG_ERROR("Failed to install any handlers");
        }

        if(!kscrashstate_init(g_stateFilePath, &context->state))
        {
            KSLOG_ERROR("Failed to initialize persistent crash state");
        }
        context->state.appLaunchTime = mach_absolute_time();
        context->config.printTraceToStdout = printTraceToStdout;
        context->config.systemInfoJSON = kssysteminfo_toJSON();
        context->config.processName = kssystemInfo_copyProcessName();
        kscrash_setUserInfoJSON(userInfoJSON);
        context->config.crashID = strdup(crashID);
        context->config.onCrashNotify = onCrashNotify;

        if(zombieCacheSize > 0)
        {
            KSLOG_DEBUG("zombieCacheSize > 0. Installing zombie handler.");
            kszombie_install(zombieCacheSize);
        }

        KSLOG_DEBUG("Installation complete.");
        return true;
    }

    KSLOG_ERROR("Called more than once");
    return false;
}