2

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 from PHImageManager requestImageDataForAsset. When we attempt to access it using NSData.bytes+NSData.length it crashes with EXC_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):

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 ...
scosman
  • 2,343
  • 18
  • 34
  • Could you perhaps show the actual code? And crash log? – matt Feb 04 '19 at 16:53
  • @matt added code. – scosman Feb 04 '19 at 17:43
  • Still don't know which line crashes or what the crash log looks like. – matt Feb 04 '19 at 18:06
  • 1
    Is it possible that there is an image that only has 1 byte of information? That would cause bad access. If you're going to access multiple bytes of information, I would suggest changing your `if` statement to return if `length <= {minimum num of bytes accessed}` – Stonz2 Feb 04 '19 at 18:36
  • I think @Stonz2 is correct. You check whether `imageData.length` is zero and bail out but in case there is only one byte of data (e.g. by a defective photo) the accesses to load `b` and `d` will fail. I recommend to add some logging code, e.g. for the length of imageData – mschmidt Feb 04 '19 at 19:07
  • @Stonz2 Ah, that's a bug in me trying to make the snippet shorter and easier to read what's happening for stack overflow. I'll update it to the exact code which didn't have that issue. Good catch, but not root cause. Edit: updated now. – scosman Feb 04 '19 at 19:26
  • Can you post a crash log? – bbum Feb 04 '19 at 20:21
  • 1
    You have radically shifted your ground on what you claim the code is, and you still have not answered key questions about the crash. It is best not to be coy about these things. The more real info you give, the likelier it is that someone can help. – matt Feb 04 '19 at 21:37
  • So crashing is `CC_MD5_Update`, try to use just `CC_MD5` – Cy-4AH Feb 05 '19 at 15:59

0 Answers0