in Crashlytics/Crashlytics/Components/FIRCLSContext.m [80:239]
bool FIRCLSContextInitialize(FIRCLSInternalReport* report,
FIRCLSSettings* settings,
FIRCLSFileManager* fileManager) {
FIRCLSContextInitData initDataObj = FIRCLSContextBuildInitData(report, settings, fileManager);
FIRCLSContextInitData* initData = &initDataObj;
if (!initData) {
return false;
}
FIRCLSContextBaseInit();
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
if (!FIRCLSIsValidPointer(initData->rootPath)) {
return false;
}
NSString* rootPath = [NSString stringWithUTF8String:initData->rootPath];
// setup our SDK log file synchronously, because other calls may depend on it
_firclsContext.readonly->logPath = FIRCLSContextAppendToRoot(rootPath, @"sdk.log");
if (!FIRCLSUnlinkIfExists(_firclsContext.readonly->logPath)) {
FIRCLSErrorLog(@"Unable to write initialize SDK write paths %s", strerror(errno));
}
// some values that aren't tied to particular subsystem
_firclsContext.readonly->debuggerAttached = FIRCLSProcessDebuggerAttached();
dispatch_group_async(group, queue, ^{
FIRCLSHostInitialize(&_firclsContext.readonly->host);
});
dispatch_group_async(group, queue, ^{
_firclsContext.readonly->logging.errorStorage.maxSize = 0;
_firclsContext.readonly->logging.errorStorage.maxEntries =
initData->errorsEnabled ? initData->maxCustomExceptions : 0;
_firclsContext.readonly->logging.errorStorage.restrictBySize = false;
_firclsContext.readonly->logging.errorStorage.entryCount =
&_firclsContext.writable->logging.errorsCount;
_firclsContext.readonly->logging.errorStorage.aPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportErrorAFile);
_firclsContext.readonly->logging.errorStorage.bPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportErrorBFile);
_firclsContext.readonly->logging.logStorage.maxSize = initData->maxLogSize;
_firclsContext.readonly->logging.logStorage.maxEntries = 0;
_firclsContext.readonly->logging.logStorage.restrictBySize = true;
_firclsContext.readonly->logging.logStorage.entryCount = NULL;
_firclsContext.readonly->logging.logStorage.aPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportLogAFile);
_firclsContext.readonly->logging.logStorage.bPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportLogBFile);
_firclsContext.readonly->logging.customExceptionStorage.aPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportCustomExceptionAFile);
_firclsContext.readonly->logging.customExceptionStorage.bPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportCustomExceptionBFile);
_firclsContext.readonly->logging.customExceptionStorage.maxSize = 0;
_firclsContext.readonly->logging.customExceptionStorage.restrictBySize = false;
_firclsContext.readonly->logging.customExceptionStorage.maxEntries =
initData->maxCustomExceptions;
_firclsContext.readonly->logging.customExceptionStorage.entryCount =
&_firclsContext.writable->exception.customExceptionCount;
_firclsContext.readonly->logging.userKVStorage.maxCount = initData->maxKeyValues;
_firclsContext.readonly->logging.userKVStorage.incrementalPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportUserIncrementalKVFile);
_firclsContext.readonly->logging.userKVStorage.compactedPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportUserCompactedKVFile);
_firclsContext.readonly->logging.internalKVStorage.maxCount = 32; // Hardcode = bad
_firclsContext.readonly->logging.internalKVStorage.incrementalPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportInternalIncrementalKVFile);
_firclsContext.readonly->logging.internalKVStorage.compactedPath =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportInternalCompactedKVFile);
FIRCLSUserLoggingInit(&_firclsContext.readonly->logging, &_firclsContext.writable->logging);
});
dispatch_group_async(group, queue, ^{
_firclsContext.readonly->binaryimage.path =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportBinaryImageFile);
FIRCLSBinaryImageInit(&_firclsContext.readonly->binaryimage,
&_firclsContext.writable->binaryImage);
});
dispatch_group_async(group, queue, ^{
NSString* rootPath = [NSString stringWithUTF8String:initData->previouslyCrashedFileRootPath];
NSString* fileName = [NSString stringWithUTF8String:FIRCLSCrashedMarkerFileName];
_firclsContext.readonly->previouslyCrashedFileFullPath =
FIRCLSContextAppendToRoot(rootPath, fileName);
});
// To initialize Crashlytics handlers even if the Xcode debugger is attached, replace this check
// with YES. Note that this is only possible to do on an actual device as it will cause the
// simulator to crash.
if (!_firclsContext.readonly->debuggerAttached) {
#if CLS_SIGNAL_SUPPORTED
dispatch_group_async(group, queue, ^{
_firclsContext.readonly->signal.path =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportSignalFile);
FIRCLSSignalInitialize(&_firclsContext.readonly->signal);
});
#endif
#if CLS_MACH_EXCEPTION_SUPPORTED
dispatch_group_async(group, queue, ^{
_firclsContext.readonly->machException.path =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportMachExceptionFile);
FIRCLSMachExceptionInit(&_firclsContext.readonly->machException);
});
#endif
dispatch_group_async(group, queue, ^{
_firclsContext.readonly->exception.path =
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportExceptionFile);
_firclsContext.readonly->exception.maxCustomExceptions =
initData->customExceptionsEnabled ? initData->maxCustomExceptions : 0;
FIRCLSExceptionInitialize(&_firclsContext.readonly->exception,
&_firclsContext.writable->exception);
});
} else {
FIRCLSSDKLog("Debugger present - not installing handlers\n");
}
dispatch_group_async(group, queue, ^{
const char* metaDataPath = [[rootPath stringByAppendingPathComponent:FIRCLSReportMetadataFile]
fileSystemRepresentation];
if (!FIRCLSContextRecordMetadata(metaDataPath, initData)) {
FIRCLSSDKLog("Unable to record context metadata\n");
}
});
// At this point we need to do two things. First, we need to do our memory protection *only* after
// all of these initialization steps are really done. But, we also want to wait as long as
// possible for these to be complete. If we do not, there's a chance that we will not be able to
// correctly report a crash shortly after start.
// Note at this will retain the group, so its totally fine to release the group here.
dispatch_group_notify(group, queue, ^{
_firclsContext.readonly->initialized = true;
__sync_synchronize();
if (!FIRCLSAllocatorProtect(_firclsContext.allocator)) {
FIRCLSSDKLog("Error: Memory protection failed\n");
}
});
if (dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, FIRCLSContextInitWaitTime)) !=
0) {
FIRCLSSDKLog("Error: Delayed initialization\n");
}
return true;
}