We have an issue where a bug with iOS is causing our app to crash. It only happened for 0.001% of users, but when it happens it makes the app unusable (crash on launch).
The problem is, the root bug is in Apple's iOS code and not something we can fix directly. We're looking for help finding a workaround, not a root cause fix.
- The crash is
EXC_BAD_ACCESS
. - We don't create the data address being read. We're getting a
NSData
fromPHImageManager requestImageDataForAsset
. When we attempt to access it usingNSData.bytes
+NSData.length
it crashes withEXC_BAD_ACCESS
. - It's a real memory address (not 0x00000000) but our app isn't allowed to access it. It looks like the NSData we get back from PHImageManager has an invalid pointer or invalid length.
- This is very uncommon. It only happens for 0.001% of users, so it's likely a rare issue from a single bad photo in their library.
- It's not transient. Whatever the bad photo is causing this, it happens ever time the app launches for that user (we access the last 12 photos in your camera roll on launch).
The question is how can we workaround this crash. I know it's always best to fix the root cause, but in this case the root cause isn't in our code (the NSData returned by an apple library is invalid). We don't know it's invalid until we try to access it, and then it's too late.
Ideas we tried (and failed):
- Catching EXC_BAD_ACCESS doesn't seem to be possible: Is there a way to catch or handle EXC_BAD_ACCESS?
Any ideas for a workaround?
Here is example code that will trigger this. It works for 99.9999% of photos, but fatal when it fails. How can I catch the issue when the NSData is invalid?
[[PHImageManager defaultManager] requestImageDataForAsset:asset
options:opts
resultHandler:^(NSData* imageData, NSString* dataUTI, UIImageOrientation orientation, NSDictionary* info) {
if (!imageData || imageData.length == 0) {
return;
}
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
CC_MD5_Update(&md5, imageData.bytes, (CC_LONG)imageData.length);
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &md5);
}];
Crash log
0 libcorecrypto.dylib md5_compress + 60
1 libcorecrypto.dylib ccdigest_update + 264
2 libcommonCrypto.dylib CC_MD5_Update + 188
... app code above ...