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.

Answered by hubauer in 385386022

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.

Incident Identifier: 7A9281BF-EB63-47CF-BEE8-460E68CC2B45

CrashReporter Key: 06be47b1c91afef9b50c551c295c757b6b152510

Hardware Model: iPhone9,1

Process: *** [1822]

Path: /private/var/containers/Bundle/Application/47D8070F-B20F-4ADC-9E8D-8F43997B480C/***.app/***

Identifier: com.***.***

Version: 633 (5.2.0)

AppStoreTools: 11A1002b

AppVariant: 1:iPhone9,1:13

Code Type: ARM-64 (Native)

Role: unknown

Parent Process: launchd [1]

Coalition: com.***.*** [1934]





Date/Time: 2019-09-15 07:16:48.9724 +0800

Launch Time: 2019-09-15 07:15:14.7595 +0800

OS Version: iPhone OS 13.1 (17A5837a)

Release Type: Beta

Baseband Version: 7.00.01

Report Version: 104



Exception Type: EXC_BAD_ACCESS (SIGBUS)

Exception Subtype: KERN_MEMORY_ERROR at 0x00000001028bb3b4

VM Region Info: 0x1028bb3b4 is in 0x102878000-0x1028bc000; bytes after start: 275380 bytes before end: 3147

REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL

__LINKEDIT 0000000102734000-0000000102878000 [ 1296K] r--/r-- SM=COW

---> mapped file 0000000102878000-00000001028bc000 [ 272K] r--/rw- SM=COW ...t_id=3eb67cef

Kernel Alloc Once 00000001028bc000-00000001028c4000 [ 32K] rw-/rwx SM=PRV



Termination Signal: Bus error: 10

Termination Reason: Namespace SIGNAL, Code 0xa

Terminating Process: exc handler [1822]

Triggered by Thread: 14

Thread 14 name:

Thread 14 Crashed:

0 libdyld.dylib 0x00000001a38356c0 dyld3::closure::ObjCStringTable::hash(char const*, unsigned long) const + 16 (Closure.cpp:1339)

1 libdyld.dylib 0x00000001a3835cd4 dyld3::closure::ObjCStringTable::getIndex(char const*) const + 52 (Closure.h:840)

2 libdyld.dylib 0x00000001a3835b54 dyld3::closure::ObjCClassOpt::forEachClass(char const*, dyld3::Array<std::__1::pair<unsigned long... + 52 (Closure.cpp:1397)

3 libdyld.dylib 0x00000001a38424f8 dyld3::AllImages::forEachObjCClass(char const*, void (void*, bool, bool*) block_pointer) const + 132 (AllImages.cpp:1922)

4 libobjc.A.dylib 0x00000001a3774c38 getPreoptimizedClass + 148 (objc-opt.mm:279)

5 libobjc.A.dylib 0x00000001a375f8d8 getClassExceptSomeSwift(char const*) + 20 (objc-runtime-new.mm:1607)

6 libobjc.A.dylib 0x00000001a3760784 look_up_class + 100 (objc-runtime-new.mm:6843)

7 Foundation 0x00000001a3df2b00 NSClassFromString + 200 (NSObjCRuntime.m:0)

8 Foundation 0x00000001a3de3264 _decodeObjectBinary + 1708 (NSKeyedArchiver.m:2472)

9 Foundation 0x00000001a3de2928 _decodeObject + 340 (NSKeyedArchiver.m:3013)

10 Foundation 0x00000001a3cf2050 -[NSKeyedUnarchiver decodeObjectForKey:] + 168 (NSKeyedArchiver.m:3035)

11 Foundation 0x00000001a3cf1eac -[NSKeyedUnarchiver decodeObjectOfClasses:forKey:] + 352 (NSKeyedArchiver.m:3069)

12 Foundation 0x00000001a3cf1b04 -[NSCoder(Exceptions) __tryDecodeObjectForKey:error:decodeBlock:] + 96 (NSCoder.m:557)

13 Foundation 0x00000001a3cf1a7c -[NSCoder decodeTopLevelObjectOfClasses:forKey:error:] + 108 (NSCoder.m:360)

14 LocationSupport 0x00000001aad4b170 CLConnectionMessage::getObjectOfClasses(NSSet*) const + 176 (CLConnection.mm:690)

15 CoreLocation 0x00000001a6b4890c invocation function for block in _CLClientCreateConnection(__CLClient*) + 224 (CLClient.mm:1155)

16 LocationSupport 0x00000001aad4ff64 invocation function for block in CLConnectionClient::setDefaultMessageHandler(void (std::__1::sha... + 68 (CLConnectionClient.mm:379)

17 LocationSupport 0x00000001aad4fe90 invocation function for block in CLConnectionClient::setDefaultMessageHandler(void (std::__1::sha... + 140 (CLCallbackDropManager.h:46)

18 LocationSupport 0x00000001aad496ec CLConnection::handleMessage(std::__1::shared_ptr<CLConnectionMessage>) + 180 (CLConnection.mm:232)

19 LocationSupport 0x00000001aad495a4 invocation function for block in CLConnection::initializeConnection_nl() + 60 (CLConnection.mm:210)

20 LocationSupport 0x00000001aad4b828 invocation function for block in setEventHandler(NSObject<OS_xpc_object>*, void (std::__1::shared... + 484 (CLConnection.mm:348)

21 libxpc.dylib 0x00000001a35fe54c _xpc_connection_call_event_handler + 68 (connection.c:0)

22 libxpc.dylib 0x00000001a35fe8c4 _xpc_connection_mach_event + 876 (connection.c:1208)

23 libdispatch.dylib 0x00000001a36fe244 _dispatch_client_callout4 + 16 (object.m:535)

We're seeing an identical stack trace on iOS 13 devices only.


Are you utilizing the Firebase SDK by any chance? I believe that's where the issue lies.

Can confirm identical crash reports for iOS 13 devices, only.


Filed an Apple bug report #: FB7296430.

Hey, adamup928, just in case, we're observing the similar issue and yes, we're using Firebase SDK

Just in case, we're observing similar crashes, involving CLConnectionClient, however we also see some crashes not involving CLConnectionClient:


Crashed: com.apple.runningboardservices.connection.incoming
0  libdyld.dylib                  0x18c828684 dyld3::closure::ObjCStringTable::hash(char const*, unsigned long) const + 16
1  libdyld.dylib                  0x18c828c98 dyld3::closure::ObjCStringTable::getIndex(char const*) const + 52
2  libdyld.dylib                  0x18c828b18 dyld3::closure::ObjCClassOpt::forEachClass(char const*, dyld3::Array<std::__1::pair<unsigned long, unsigned long> > const&, void (void*, bool, bool*) block_pointer) const + 52
3  libdyld.dylib                  0x18c8354c4 dyld3::AllImages::forEachObjCClass(char const*, void (void*, bool, bool*) block_pointer) const + 132
4  libobjc.A.dylib                0x18c767c38 getPreoptimizedClass + 148
5  libobjc.A.dylib                0x18c7528d8 getClassExceptSomeSwift(char const*) + 20
6  libobjc.A.dylib                0x18c753784 look_up_class + 100
7  Foundation                     0x18cde52ec NSClassFromString + 200
8  BaseBoard                      0x18f5c0b2c _BSXPCDecodeObject + 2000
9  BaseBoard                      0x18f5be49c _BSXPCDecodeObjectForKey + 288
10 RunningBoardServices           0x18f55976c -[RBSXPCMessage decodeArgumentCollection:withClass:atIndex:allowNil:error:] + 416
11 RunningBoardServices           0x18f545da8 __32-[RBSConnection _handleMessage:]_block_invoke_2.337 + 92
12 libsystem_trace.dylib          0x18c5d3708 _os_activity_initiate_impl + 56
13 RunningBoardServices           0x18f5459d0 -[RBSConnection _handleMessage:] + 784
14 RunningBoardServices           0x18f5464fc __30-[RBSConnection _lock_connect]_block_invoke + 88
15 libxpc.dylib                   0x18c5f258c _xpc_connection_call_event_handler + 68
16 libxpc.dylib                   0x18c5f2904 _xpc_connection_mach_event + 876
17 libdispatch.dylib              0x18c6f128c _dispatch_client_callout4 + 16
18 libdispatch.dylib              0x18c6adc64 _dispatch_mach_msg_invoke$VARIANT$mp + 380
19 libdispatch.dylib              0x18c69d3f0 _dispatch_lane_serial_drain$VARIANT$mp + 300
20 libdispatch.dylib              0x18c6ae864 _dispatch_mach_invoke$VARIANT$mp + 472
21 libdispatch.dylib              0x18c69d3f0 _dispatch_lane_serial_drain$VARIANT$mp + 300
22 libdispatch.dylib              0x18c69df48 _dispatch_lane_invoke$VARIANT$mp + 468
23 libdispatch.dylib              0x18c6a7400 _dispatch_workloop_worker_thread + 588
24 libsystem_pthread.dylib        0x18c740fa8 _pthread_wqthread + 276
25 libsystem_pthread.dylib        0x18c743ae4 start_wqthread + 8

In our case it looks like it's an issue with lack of background fetch capability that results in watchdog killing the app. We're able to reproduce it with the steps in https://github.com/firebase/firebase-ios-sdk/issues/3759

We are seeing both of those exact same crashes on iOS 13. We are not using Firebase.

Accepted Answer

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.

Hello, we are seeing similar crashes like this as well. Did you find any conclusive evidence or more information about the NSFileProtectionComplete and the crash? Thanks 🙂

It seems that the dyld3 saves the generated clojure files in the app tmp directory and if you use NSFileProtectionComplete the clojure files have this property too. To generate a crahs close the app, lock the phone, send a push that will wake up the app and then the crash is generated.

The solution seems to be simple, just change the permissions for the app tmp direcptry to NSFileProtectionCompleteUntilFirstUserAuthentication and the app will not crash.

I really don't know why apple did this.

We have the same issue but it does not seem to be solved by the fix recommended by Alex T. Has anybody else tried this?


This is completely baffling. Currently running ios 13.1.2, and the primary issue is only seen on XR. I can force a crash by turning the phone to horizontal orientation right as I lock it (which causes a split screen in our app on larger phones like XR).


We have noticed that when we do not allow Location (While in use), we do not get the first exception with CoreLocation. But then we get the com.apple.runningboardservices.connection.incoming or a BSXPCCNx:com.apple.frontboard.systemappservices crash. Either way, the stack trace ends in the dyld3::closure.


Looking back, this didn't start when I updated to iOS 13 beta. It didn't even start when I was using the XCode 11 beta. Somewhere around the time I switched to XCode 11 it started, but we didn't notice it at first. If I load the build prior to that from TestFlight, built with XCode 11 (GM seed I think), no crash. Also, it will not crash if built/loaded from XCode (DEBUG version), but only from TestFlight or App Store.


Since I know which build the crashes started with, I went back to an older commit and rebuilt source code from there. It still crashes.

I removed XCode 11 entirely (and the various cached files), installed XCode 10.3 and rebuilt, but it is still crashing.


I realized that I had also started a new branch right around the time it broke and added a Personal VPN entitlement in the new branch, which forced me to update my Provisioning Profile. When we noticed the crashing, I switched back to the main branch to try to fix. Completely grasping at straws by this point, just in case it mattered, I even removed the Personal VPN entitlement and deleted all old provisioning profiles. It is still crashing.


I have uninstalled/reinstalled the app several times after various attempts at fixes too just in case it helped. I may open a support ticket or repost this in a different thread, but thought I'd see if anyone here tried Alex T's suggestion or tried other things that might work?


I can't release our app like this, but I also currently changed the app wide Data Protection entitlement from NSFileProtectionComplete to NSFileProtectionCompleteUntilFirstUserAuthentication (which I think is default) just to see if that chagnes anything. Waiting for TestFlight to finish processing to test that.

Looks like changing the app wide Data Protection entitlement from NSFileProtectionComplete to NSFileProtectionCompleteUntilFirstUserAuthentication instead of just the temp directory worked (though more testing is needed). But that creates other issues for us. Anyone know if this is on Apple's radar?

Feedback filed. The ticket number is FB7347161.


I've figured out a set of steps that causes the crash every time when the Data Protection entitlement is enabled. As soon as data protection is turned off, a crash does not occur.


These steps will cause a crash even on an unmodified Xcode application template (single-view application, for example):


Steps to reproduce:


  1. Run application without debugger attached (to enable watchdog timers)
  2. Lock device (while the application is in the foreground)
  3. Wait 15 seconds
  4. Rotate device to landscape while locked (give it a good shake so you know the new orientation has been recognized)
  5. Wake and unlock device
  6. App has crashed

I'm seeing similar crash reports appearing in organizer. It is not something I am able to reproduce, the suggestions here don't cause it for me. Only one instance has been an Xr. Others have been XS Max, 6s+, 7, 8+ so is something that could happen on any device.


I do have NSFileProtectionComplete set as the app default like others, just no way of seeing if that fixes the problem short of pushing an update with it changed.

@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!

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