App crash on iOS 13 with dyld3::closure::ObjCStringTable::hash(char const*, unsigned long)

Our App runs well in iOS 12, but recently we found on iOS 13 beta there are some rare crashes. I spent a lot of time investigating it, but I still haven’t solved it. Can anybody help me.

Accepted Reply

Are you using NSFileProtectionComplete in your entitlements? We found a *strong* correlation between using NSFileProtectionComplete and the crash, which would happen soon after device lock.


We were able to temporarily work around this issue by switching to NSFileProtectionCompleteUntilFirstUserAuthentication, then locking specific directories with NSFileProtectionComplete.

Replies

@Daveak - I updated my reproduction steps above with some more detail. We're able to generate a crash without fail, even on an unmodified Xcode application template. To run in Xcode without the debugger, but still see logs, Edit Scheme -> Info -> Uncheck "Debug Executable"


Hope this helps you reproduce and test the effects of changing the Data Protection entitlement.

Thanks! Let us know if you hear anything back!

HI Alex,


We really can't change the entitlements from NSFileProtectionComplete to NSFileProtenctionUntilFirstUserAuthentication, since this opens our app database and exposes it which our ethical hacking team won't allow. I see a lot have been experiencing this so I hope Apple comes up with an explanation on why this is happening. This crash happens regardless of the Xcode version used to build the app.

I had the same Issue, I was able to fix this adding a delay, when app will enter foreground and before it accesses to CoreData.


My issue was there I was accessing to CoreData in applicationWillEnterForeground, and seems that the data is encrypted yet, I added a delay of 3 secods, and now it works fine.

I had the same Issue, I was able to fix this adding a delay, when app will enter foreground and before it accesses to CoreData.


My issue was there I was accessing to CoreData in applicationWillEnterForeground, and seems that the data is encrypted yet, I added a delay of 3 secods, and now it works fine.

You don't need to change the value in the entitlements to fix this issue. My understanding is that the value in the entitlements file is only used for the initial configuration of your app's data container when your app is first installed, but after that, any new files or directories are given the protection of the containing directory (unless you manually specify a different protection level when creating the item). So even if you were to change the protection in your entitlements, users who installed your update wouldn't see the benefits unless they did a clean install. (In situations unrelated to this one, I've seen sources online mention mixed results when changing the protection level defined in the entitlements.)


Instead of changing the protection in the entitlements, you should be able to change the protection level for just the tmp/com.apple.dyld folder, and then it should work from then on. This allows the remainder of your data to stay at complete protection, and only the temporary files generated by com.apple.dyld will have the complete until first authentication protection. In my research, I've found you may need to temporarily add POSIX write permissions to the folder before being able to change the file protection. I also recursively changed the protection of every item in the directory for my first attempt, but I'm thinking that may be unnecessary since the filenames include the UUID of the main executable, which will change every time you compile your app.

I turned off the feature in our latest version and it seems solved a lot of background crash issues, but there are still a lot of similar crashes.

can you specify, where is the tmp/com.apple.dyld folder located?

The temporary directory can be found using the following:

FileManager.default.temporaryDirectory.appendingPathComponent("com.apple.dyld")


I can also confirm that, at least in my case, I needed to change posix permissions and perform the operations on the items in the directory like I mentioned in my original reply. If I didn't change the posix permissions, the file protection I specified wasn't actually persisted. As far as applying the change recursively, by the time my code to fix the issue was executed, the closure file had already been generated with the wrong protection. It's possible this is happening because I didn't do this first thing when my app started, but I didn't want to take a chance on it.


It might be worth looking into just finding the closure file for the currently running image (so you don't have to recursively traverse the file system during startup), but the app I'm working on is written with Xamarin which makes it a little more difficult for me to find the image id. Theoretically though, you could use this information to change the protection of just the com.apple.dyld folder and the current closure file, so this would be significantly less invasive and more performant. There would likely be a smaller chance of breaking things, since you'd potentially modify less files in the future if Apple ever decided to store more files in that directory.

Just heard back from Apple DTS. The Data Protection entitlement issues are fixed in iOS 13.2 Beta 3. I can no longer reproduce the issue.


Thanks all for the dialog and contributions!

Great news! Thanks for the update!

In which moment do we need to change the protection level for the Temp Directory?

One of the easiest way to reproduce the crash is

1. When app is running, lock the phone

2. Do mobile call and receive on device

3. The app goes to background and crash.


The crash is 100% reproduciable

With iOS 13.2 beta 3, the crash is not reproducible with above mentioned step. Looks like the issue was from Apple and they have taken care in 13.2 release

I could reproduce this on iOS 13.1 but can no longer reproduce it on 13.2 beta 4. Do you still see this issue when you revert to NSFileProtectionComplete?