Insight into BaseBoard/FrontBoardServices Crashes Needed

We're seeing a sharp uptick in BaseBoard/FrontBoardServices crashes since we migrated from UIApplicationDelegate to UIWindowSceneDelegate. Having exhausted everything on my end short of reverse engineering BaseBoard or making changes without being able to know if they work, I need help. I think all I need to get unstuck is an answer to these questions, if possible:

  1. What does -[BSSettings initWithSettings:] enumerate over? If I know what's being enumerated, I'll know what to look for in our app.

  2. What triggers FrontBoardServices to do this update? If I can reproduce the crash--or at least better understand when it may happen--I will be better able to fix it

Here's two similar stack traces:

Since these are private trameworks, there is no documentation or information on their behavior that I can find.

There are other forum posts regarding this crash, on here and on other sites. However, I did not find any that shed any insight on the cause or conditions of the crash. Additionally, this is on iPhone, not macOS, and not iPad. This post is different, because I'm asking specific questions that can be answered by someone with familiarity on how these internal frameworks work. I'm not asking for help debugging my application, though I'd gladly take any suggestions/tips!


Here's the long version, in case anyone finds it useful:

In our application, we have seen a sharp rise in crashes in BaseBoard and FrontBoardServices, which are internal iOS frameworks, since we migrated our app to use UIWindowSceneDelegate. We were using exclusively UIApplicationDelegate before. The stack traces haven't proven very useful yet, because we haven't been able to reproduce the crashes ourselves.

Upon searching online, we have learned that Baseboard/Frontsoardservices are probably copying scene settings upon something in the scene changing. Based on our crash reports, we know that most of our users are on an iPhone, not an iPad or macOS, so we can rule out split screen or window resizing. Our app is locked to portrait as well, so we can also rule out orientation changes. And considering the stack trace is in the middle of an objc_retain_x2 call, which is itself inside of a collection enumeration, we are assuming that whatever is being enumerated probably was changed or deallocated during enumeration. Sometimes it's objc_retain_x2, and sometimes it's a release call. And sometimes it's a completely different stack trace, but still within BaseBoard/FrontBoardServices. I suspect these all share the same cause.

Because it's thread 0 that crashed, we know that BaseBoard/FrontBoardServices were running on the main thread, which means that for this crash to occur, something might be changing on a background thread. This is what leads me to suspect a race condition.

There are many places in our app where we accidentally update the UI from a background thread. We've fixed many of them, but I'm sure there are more. Our app is large. Because of this, I think background UI are the most likely cause. However, since I can't reproduce the crash, and because none of our stack traces clearly show UI updates happening on another thread at the same time, I am not certain.


And here's the stack trace inline, in case the attachments expire or search engines can't read them:

Thread 0 name:
Thread 0 Crashed:
objc_retain_x2 (libobjc.A.dylib)
BSIntegerMapEnumerateWithBlock (BaseBoard)
-[BSSettings initWithSettings:] (BaseBoard)
-[BSKeyedSettings initWithSettings:] (BaseBoard)
-[FBSSettings _settings:] (FrontBoardServices)
-[FBSSettings _settings] (FrontBoardServices)
-[FBSSettingsDiff applyToMutableSettings:] (FrontBoardServices)
-[FBSSettingsDiff settingsByApplyingToMutableCopyOfSettings:] (FrontBoardServices)
-[FBSSceneSettingsDiff settingsByApplyingToMutableCopyOfSettings:] (FrontBoardServices)
-[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 (FrontBoardServices)
-[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke.cold.1 (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke (FrontBoardServices)
_dispatch_client_callout (libdispatch.dylib)
_dispatch_block_invoke_direct (libdispatch.dylib)
__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ (FrontBoardServices)
-[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] (FrontBoardServices)
-[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] (FrontBoardServices)
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (CoreFoundation)
__CFRunLoopDoSource0 (CoreFoundation)
__CFRunLoopDoSources0 (CoreFoundation)
__CFRunLoopRun (CoreFoundation)
CFRunLoopRunSpecific (CoreFoundation)
GSEventRunModal (GraphicsServices)
-[UIApplication _run] (UIKitCore)
UIApplicationMain (UIKitCore)
(null) (UIKitCore)
main (AppDelegate.swift:0)
0x1ab8cbf08 + 0

After having spent some time in the debugger, I've learned the following:

  1. It appears that BaseBoard and FrontBoardServices are not iterating over our UI hierarchy like I had wondered. It seems to be dealing with things like UI configuration, accessibility, edge insets and safe areas, orientation, displays, etc. In other words, things that our app shouldn't be responsible for. This leads me to believe this may not be our app's bug. I don't think I have enough information for a good bug report, though.
  2. BaseBoard does work on the main thread and on background, worker threads. There's an XPC interprocess communication manager that receives messages on a background thread--I presume from the OS--about things that have changed.
  3. It may not have anything to do with a race condition. It seems plausible it could also be that BaseBoard/FrontBoardServices is getting its state corrupted.
  4. BSIntegerMapEnumerateWithBlock gets called a lot. It wasn't very useful printing out what's passed into it.

I could file a bug report, but still have no idea how to reproduce it, since I've yet to see the crash. Should I report it anyways?

We're unable to work with this crash report as we need to see the complete symbolicated Apple crash report with its original formatting preserved. Please post the complete symbolicated Apple crash report as an attachment to preserve its formatting. Posting a Crash Report explains how to do so.

You also wrote:

In our application, we have seen a sharp rise in crashes in BaseBoard and FrontBoardServices, which are internal iOS frameworks, since we migrated our app to use UIWindowSceneDelegate.

If you haven't already, it might be worth looking into how you've setup your SceneDelegate. TN3187: Migrating to the UIKit scene-based life cycle is a good starting point to compare against to see what you're doing differently.

Here's the crash report, as downloaded using Xcode's organizer. Will this work? I redacted the app and framework names. All of our symbols are symbolicated, except for "MyFramework", which is a C++ library of ours whose only job is to decode video, so I think it's irrelevant to this crash.

I'll take another look at that tech note. I've gone over it before, but maybe I'll find something if I look again. Thank you!

Insight into BaseBoard/FrontBoardServices Crashes Needed
 
 
Q