How do you investigate cryptic symbolicated crashes in your iOS apps?

There are 1–3 crashes in my app that seem to be rare race conditions. They happened so far to about 250 users of mine. I cannot reproduce them and have no clues whatsoever about their cause. For example:

          Crashed: com.apple.main-thread
0  libsystem_kernel.dylib         0xc2d4 __pthread_kill + 8
1  libsystem_pthread.dylib        0x859c pthread_kill + 268
2  libsystem_c.dylib              0x77b08 abort + 128
3  libswiftCore.dylib             0x3ccae4 swift::fatalError(unsigned int, char const*, ...) + 134
4  libswiftCore.dylib             0x3ccb04 swift::warningv(unsigned int, char const*, char*) + 30
5  libswiftCore.dylib             0x3c66cc tryCastFromClassToObjCBridgeable(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 254
6  libswiftCore.dylib             0x3c8408 tryCastToObjectiveCClass(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 88
7  libswiftCore.dylib             0x3c5d30 tryCast(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 992
8  libswiftCore.dylib             0x3c57dc swift_dynamicCast + 208
9  SwiftUI                        0x91540 PlatformViewHost.updateNestedHosts(_:colorSchemeChanged:) + 332
10 SwiftUI                        0x91110 PlatformViewHost.updateEnvironment(_:viewPhase:) + 272
11 SwiftUI                        0x27f148 specialized PlatformViewHost.init(_:host:environment:viewPhase:importer:) + 1288
12 SwiftUI                        0x27ec28 specialized PlatformViewHost.__allocating_init(_:host:environment:viewPhase:importer:) + 92
13 SwiftUI                        0x27eb88 closure #1 in closure #1 in closure #4 in closure #1 in PlatformViewChild.updateValue() + 504
14 SwiftUI                        0x27e984 partial apply for closure #1 in closure #1 in closure #4 in closure #1 in PlatformViewChild.updateValue() + 48
15 SwiftUI                        0x27e90c RepresentableContextValues.asCurrent<A>(do:) + 188
16 SwiftUI                        0x27e804 closure #1 in closure #4 in closure #1 in PlatformViewChild.updateValue() + 176
17 SwiftUI                        0x27e72c partial apply for closure #4 in closure #1 in PlatformViewChild.updateValue() + 128
18 SwiftUICore                    0x1640c partial apply for closure #1 in _withObservation<A>(do:) + 48
19 SwiftUICore                    0x14148 closure #1 in _withObservation<A>(do:)partial apply + 16
20 SwiftUICore                    0x128c8 withUnsafeMutablePointer<A, B, C>(to:_:) + 160
21 SwiftUICore                    0x7c08c StatefulRule.withObservation<A>(do:) + 872
22 SwiftUICore                    0x7bb8c StatefulRule.withObservation<A>(do:) + 72
23 SwiftUI                        0x8f374 closure #1 in PlatformViewChild.updateValue() + 3312
24 SwiftUICore                    0x204360 Signpost.traceInterval<A>(object:_:_:closure:) + 452
25 SwiftUI                        0x791ac PlatformViewChild.updateValue() + 176
26 SwiftUI                        0x78414 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32
27 AttributeGraph                 0xccac AG::Graph::UpdateStack::update() + 540
28 AttributeGraph                 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424
29 AttributeGraph                 0x3bf4 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720
30 AttributeGraph                 0x3794 AGGraphGetValue + 228
31 SwiftUI                        0x20b90 InvalidatableLeafLayoutComputer.view.getter + 60
32 SwiftUI                        0x363878 RemoteSheetContainerVCWriter.value.getter + 404
33 SwiftUI                        0x360e0 implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 324
34 AttributeGraph                 0xccac AG::Graph::UpdateStack::update() + 540
35 AttributeGraph                 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424
36 AttributeGraph                 0x3bf4 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720
37 AttributeGraph                 0x3794 AGGraphGetValue + 228
38 SwiftUICore                    0xae908 closure #1 in PairPreferenceCombiner.value.getter + 84
39 SwiftUI                        0x1ade44 protocol witness for static PreferenceKey.reduce(value:nextValue:) in conformance RemoteSheetContainerVCKey + 160
40 SwiftUICore                    0xada80 PairPreferenceCombiner.value.getter + 216
41 SwiftUICore                    0x4cb0 implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 324
42 AttributeGraph                 0xccac AG::Graph::UpdateStack::update() + 540
43 AttributeGraph                 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424
44 AttributeGraph                 0xbfd4 AG::Graph::value_ref(AG::AttributeID, unsigned int, AGSwiftMetadata const*, unsigned char&) + 288
45 AttributeGraph                 0x37e4 AGGraphGetValue + 308
46 SwiftUI                        0x31d664 closure #1 in PresentationHostingController._remoteSheet.getter + 96
47 SwiftUI                        0x31d5fc partial apply for closure #1 in PresentationHostingController._remoteSheet.getter + 20
48 SwiftUICore                    0x79184 closure #1 in static Update.ensure<A>(_:) + 56
49 SwiftUICore                    0x79108 static Update.ensure<A>(_:) + 100
50 SwiftUI                        0x31d860 PresentationHostingController._remoteSheet.getter + 264
51 SwiftUI                        0x31d730 @objc PresentationHostingController._remoteSheet.getter + 28
52 UIKitCore                      0x356b20 -[UISheetPresentationController _expectedRemoteSheet] + 244
53 UIKitCore                      0x3553b0 -[UISheetPresentationController presentationTransitionWillBegin] + 1124
54 UIKitCore                      0x36d4cc -[_UIFormSheetPresentationController presentationTransitionWillBegin] + 56
55 UIKitCore                      0x36bd5c __80-[UIPresentationController _initViewHierarchyForPresentationSuperview:inWindow:]_block_invoke + 2136
56 UIKitCore                      0x3111c4 __77-[UIPresentationController runTransitionForCurrentStateAnimated:handoffData:]_block_invoke_3 + 304
57 UIKitCore                      0x9fd40 -[_UIAfterCACommitBlock run] + 72
58 UIKitCore                      0x9f894 -[_UIAfterCACommitQueue flush] + 164
59 UIKitCore                      0x9f7a8 _runAfterCACommitDeferredBlocks + 260
60 UIKitCore                      0x9f4c8 _cleanUpAfterCAFlushAndRunDeferredBlocks + 80
61 UIKitCore                      0x9f3d8 _UIApplicationFlushCATransaction + 72
62 UIKitCore                      0x9c890 __setupUpdateSequence_block_invoke_2 + 332
63 UIKitCore                      0x9c704 _UIUpdateSequenceRun + 84
64 UIKitCore                      0x9f034 schedulerStepScheduledMainSection + 172
65 UIKitCore                      0x9cc50 runloopSourceCallback + 92
66 CoreFoundation                 0x73f3c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
67 CoreFoundation                 0x73ed0 __CFRunLoopDoSource0 + 176
68 CoreFoundation                 0x76b30 __CFRunLoopDoSources0 + 244
69 CoreFoundation                 0x75d2c __CFRunLoopRun + 840
70 CoreFoundation                 0xc8274 CFRunLoopRunSpecific + 588
71 GraphicsServices               0x14c0 GSEventRunModal + 164
72 UIKitCore                      0x3ee77c -[UIApplication _run] + 816
73 UIKitCore                      0x14e64 UIApplicationMain + 340
74 SwiftUI                        0x292660 closure #1 in KitRendererCommon(_:) + 168
75 SwiftUI                        0x292590 runApp<A>(_:) + 100
76 SwiftUI                        0x292474 static App.main() + 180
77 MyApp                          0x19d82c main + 4335982636 (MyApp.swift:4335982636)
78 ???                            0x1adb84de8 (Missing)

There’s no reference to any specific code of mine—no clues at all.

AFAIK, I’m following best practices, such as manipulating SwiftUI state only on the main thread, using actors where appropriate, etc.

How would you suggest investigating or tackling such errors? They seem completely inactionable.

1 Like

Hi, Xcode should symbolize the crash log automatically in organizer. If it‘s not happening, you can try this: ios - How to symbolicate crash log Xcode? - Stack Overflow

Hi @flexlixrup , thanks, but I believe this crash is already fully symbolicated, isn't it?

Looks a crash within SwiftUI's runtime. Unless you can reproduce it locally, I'd suggest starting by looking at the changes since the last build that didn't have the crash, then you can experiment with restructuring things to see if the crash still happens.

Hi @Jon_Shier , that's a good idea, but my app is new, 3 weeks old, and has had this crash from its infancy.

I also tried reviewing the logs to roughly determine where it happens, but to no avail—I couldn’t find any pattern significant enough to make a guess.

Looking at the stack this appears to be something presented in a sheet, so that might be another place to look.

1 Like

A few suggestions:

Go back to stack frame 9 and earlier, select the method name, google it. You're looking for posts from other people that have this same crash. There are some on the Apple forum. They seem to think it's an Apple bug.

You can set breakpoints on these methods even though they're not in your code. You might be able to figure out where in your code they get called.

If you are logging then add log statements to every screen in your app. Make a new release and look for the logs when it crashes to see which screen(s) it's on.

Good luck.

5 Likes

@Jon_Shier Thanks for the insight.

Thanks @phoneyDev , Googling haven't led me to the solution, and debugging is not relevant in my case since I have never experienced this bug personally (quite rare), but I will try to go down the logging route.