Skip to content

Commit 454fa83

Browse files
authored
Get rid of objc blocks inside dyld callback (#10014)
1 parent 3590ebb commit 454fa83

File tree

5 files changed

+82
-39
lines changed

5 files changed

+82
-39
lines changed

Crashlytics/Crashlytics/Components/FIRCLSBinaryImage.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ typedef struct {
6464
FIRCLSBinaryImageRuntimeNode nodes[CLS_BINARY_IMAGE_RUNTIME_NODE_COUNT];
6565
} FIRCLSBinaryImageReadWriteContext;
6666

67-
void FIRCLSBinaryImageInit(FIRCLSBinaryImageReadOnlyContext* roContext,
68-
FIRCLSBinaryImageReadWriteContext* rwContext);
67+
void FIRCLSBinaryImageInit(void);
6968

7069
#if CLS_COMPACT_UNWINDING_SUPPORTED
7170
bool FIRCLSBinaryImageSafeFindImageForAddress(uintptr_t address,

Crashlytics/Crashlytics/Components/FIRCLSBinaryImage.m

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ static void FIRCLSBinaryImageChanged(bool added,
5151
static void FIRCLSBinaryImageRecordSlice(bool added, const FIRCLSBinaryImageDetails imageDetails);
5252

5353
#pragma mark - Core API
54-
void FIRCLSBinaryImageInit(FIRCLSBinaryImageReadOnlyContext* roContext,
55-
FIRCLSBinaryImageReadWriteContext* rwContext) {
54+
void FIRCLSBinaryImageInit(void) {
5655
// initialize our node array to all zeros
5756
memset(&_firclsContext.writable->binaryImage, 0, sizeof(_firclsContext.writable->binaryImage));
5857
_firclsContext.writable->binaryImage.file.fd = -1;
@@ -281,6 +280,37 @@ static bool FIRCLSBinaryImageMachOSliceInitSectionByName(FIRCLSMachOSliceRef sli
281280
return true;
282281
}
283282

283+
static void FIRCLSPopulateImageDetailWithLoadCommand(uint32_t type,
284+
uint32_t size,
285+
const struct load_command* cmd,
286+
void* context) {
287+
FIRCLSBinaryImageDetails* details = context;
288+
switch (type) {
289+
case LC_UUID: {
290+
const uint8_t* uuid = FIRCLSMachOGetUUID(cmd);
291+
FIRCLSSafeHexToString(uuid, 16, details->uuidString);
292+
} break;
293+
case LC_ENCRYPTION_INFO:
294+
details->encrypted = FIRCLSMachOGetEncrypted(cmd);
295+
break;
296+
case LC_SEGMENT:
297+
case LC_SEGMENT_64: {
298+
FIRCLSMachOSegmentCommand segmentCommand = FIRCLSBinaryImageMachOGetSegmentCommand(cmd);
299+
300+
if (strncmp(segmentCommand.segname, SEG_TEXT, sizeof(SEG_TEXT)) == 0) {
301+
details->node.size = segmentCommand.vmsize;
302+
}
303+
} break;
304+
case LC_VERSION_MIN_MACOSX:
305+
case LC_VERSION_MIN_IPHONEOS:
306+
case LC_VERSION_MIN_TVOS:
307+
case LC_VERSION_MIN_WATCHOS:
308+
details->minSDK = FIRCLSMachOGetMinimumOSVersion(cmd);
309+
details->builtSDK = FIRCLSMachOGetLinkedSDKVersion(cmd);
310+
break;
311+
}
312+
}
313+
284314
static bool FIRCLSBinaryImageFillInImageDetails(FIRCLSBinaryImageDetails* details) {
285315
if (!FIRCLSIsValidPointer(details)) {
286316
return false;
@@ -299,33 +329,8 @@ static bool FIRCLSBinaryImageFillInImageDetails(FIRCLSBinaryImageDetails* detail
299329
// struct types in a few different places.
300330
details->node.baseAddress = (void* volatile)details->slice.startAddress;
301331

302-
FIRCLSMachOSliceEnumerateLoadCommands(
303-
&details->slice, ^(uint32_t type, uint32_t size, const struct load_command* cmd) {
304-
switch (type) {
305-
case LC_UUID: {
306-
const uint8_t* uuid = FIRCLSMachOGetUUID(cmd);
307-
FIRCLSSafeHexToString(uuid, 16, details->uuidString);
308-
} break;
309-
case LC_ENCRYPTION_INFO:
310-
details->encrypted = FIRCLSMachOGetEncrypted(cmd);
311-
break;
312-
case LC_SEGMENT:
313-
case LC_SEGMENT_64: {
314-
FIRCLSMachOSegmentCommand segmentCommand = FIRCLSBinaryImageMachOGetSegmentCommand(cmd);
315-
316-
if (strncmp(segmentCommand.segname, SEG_TEXT, sizeof(SEG_TEXT)) == 0) {
317-
details->node.size = segmentCommand.vmsize;
318-
}
319-
} break;
320-
case LC_VERSION_MIN_MACOSX:
321-
case LC_VERSION_MIN_IPHONEOS:
322-
case LC_VERSION_MIN_TVOS:
323-
case LC_VERSION_MIN_WATCHOS:
324-
details->minSDK = FIRCLSMachOGetMinimumOSVersion(cmd);
325-
details->builtSDK = FIRCLSMachOGetLinkedSDKVersion(cmd);
326-
break;
327-
}
328-
});
332+
FIRCLSMachOSliceEnumerateLoadCommands_f(&details->slice, details,
333+
FIRCLSPopulateImageDetailWithLoadCommand);
329334

330335
// We look up the section we want, and we *should* be able to use:
331336
//
@@ -359,6 +364,19 @@ static bool FIRCLSBinaryImageFillInImageDetails(FIRCLSBinaryImageDetails* detail
359364
return true;
360365
}
361366

367+
typedef struct {
368+
FIRCLSBinaryImageDetails details;
369+
bool added;
370+
} FIRCLSImageChange;
371+
372+
static void FIRCLSProcessBinaryImageChange(void* context) {
373+
FIRCLSImageChange* imageChange = context;
374+
// this is an atomic operation
375+
FIRCLSBinaryImageStoreNode(imageChange->added, imageChange->details);
376+
FIRCLSBinaryImageRecordSlice(imageChange->added, imageChange->details);
377+
free(context);
378+
}
379+
362380
static void FIRCLSBinaryImageChanged(bool added,
363381
const struct mach_header* mh,
364382
intptr_t vmaddr_slide) {
@@ -368,14 +386,14 @@ static void FIRCLSBinaryImageChanged(bool added,
368386

369387
imageDetails.slice = FIRCLSMachOSliceWithHeader((void*)mh);
370388
imageDetails.vmaddr_slide = vmaddr_slide;
389+
// fill imageDetails fields using slice & vmaddr_slide
371390
FIRCLSBinaryImageFillInImageDetails(&imageDetails);
372391

373-
// Do these time-consuming operations on a background queue
374-
dispatch_async(FIRCLSGetBinaryImageQueue(), ^{
375-
// this is an atomic operation
376-
FIRCLSBinaryImageStoreNode(added, imageDetails);
377-
FIRCLSBinaryImageRecordSlice(added, imageDetails);
378-
});
392+
FIRCLSImageChange* change = malloc(sizeof(FIRCLSImageChange));
393+
if (!change) return;
394+
change->added = added;
395+
change->details = imageDetails;
396+
dispatch_async_f(FIRCLSGetBinaryImageQueue(), change, FIRCLSProcessBinaryImageChange);
379397
}
380398

381399
#pragma mark - In-Memory Storage
@@ -390,6 +408,7 @@ static void FIRCLSBinaryImageStoreNode(bool added, FIRCLSBinaryImageDetails imag
390408
return;
391409
}
392410

411+
// looking for an empty space if an image added
393412
void* searchAddress = NULL;
394413
bool success = false;
395414
FIRCLSBinaryImageRuntimeNode* nodes = _firclsContext.writable->binaryImage.nodes;

Crashlytics/Crashlytics/Components/FIRCLSContext.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ bool FIRCLSContextInitialize(FIRCLSContextInitData* initData, FIRCLSFileManager*
158158
_firclsContext.readonly->binaryimage.path =
159159
FIRCLSContextAppendToRoot(rootPath, FIRCLSReportBinaryImageFile);
160160

161-
FIRCLSBinaryImageInit(&_firclsContext.readonly->binaryimage,
162-
&_firclsContext.writable->binaryImage);
161+
FIRCLSBinaryImageInit();
163162
});
164163

165164
dispatch_group_async(group, queue, ^{

Crashlytics/Shared/FIRCLSMachO/FIRCLSMachO.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ typedef void (^FIRCLSMachOSliceIterator)(FIRCLSMachOSliceRef slice);
5656
typedef void (^FIRCLSMachOLoadCommandIterator)(uint32_t type,
5757
uint32_t size,
5858
const struct load_command* cmd);
59+
typedef void (*FIRCLSMachOLoadCommandIteratorFunc)(uint32_t type,
60+
uint32_t size,
61+
const struct load_command* cmd,
62+
void* context);
5963

6064
__BEGIN_DECLS
6165

@@ -69,6 +73,9 @@ struct FIRCLSMachOSlice FIRCLSMachOFileSliceWithArchitectureName(FIRCLSMachOFile
6973
void FIRCLSMachOEnumerateSlicesAtAddress(void* executableData, FIRCLSMachOSliceIterator block);
7074
void FIRCLSMachOSliceEnumerateLoadCommands(FIRCLSMachOSliceRef slice,
7175
FIRCLSMachOLoadCommandIterator block);
76+
void FIRCLSMachOSliceEnumerateLoadCommands_f(FIRCLSMachOSliceRef slice,
77+
void* context,
78+
FIRCLSMachOLoadCommandIteratorFunc function);
7279
struct FIRCLSMachOSlice FIRCLSMachOSliceGetCurrent(void);
7380
struct FIRCLSMachOSlice FIRCLSMachOSliceWithHeader(void* machHeader);
7481

Crashlytics/Shared/FIRCLSMachO/FIRCLSMachO.m

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,25 @@ static bool FIRCLSMachOSliceIsValid(FIRCLSMachOSliceRef slice) {
219219
return true;
220220
}
221221

222+
void FIRCLSMachOSliceEnumerateLoadCommands_f(FIRCLSMachOSliceRef slice,
223+
void* context,
224+
FIRCLSMachOLoadCommandIteratorFunc function) {
225+
const struct load_command* cmd;
226+
uint32_t cmdCount;
227+
228+
if (!FIRCLSMachOSliceIsValid(slice)) {
229+
return;
230+
}
231+
232+
FIRCLSMachOHeaderValues(slice, &cmd, &cmdCount);
233+
234+
for (uint32_t i = 0; cmd != NULL && i < cmdCount; ++i) {
235+
function(cmd->cmd, cmd->cmdsize, cmd, context);
236+
237+
cmd = (struct load_command*)((uintptr_t)cmd + cmd->cmdsize);
238+
}
239+
}
240+
222241
void FIRCLSMachOSliceEnumerateLoadCommands(FIRCLSMachOSliceRef slice,
223242
FIRCLSMachOLoadCommandIterator block) {
224243
const struct load_command* cmd;

0 commit comments

Comments
 (0)