Hello
I started using CLMonitor on my App, and I am noticing the following crash on Xcode Organizer for dozens of my app users:
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000001
Exception Codes: 0x0000000000000001, 0x0000000000000001
VM Region Info: 0x1 is not in any region. Bytes before following region: ………….
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT ………-…….. [ 176K] r-x/r-x SM=COW /var/containers/Bundle/Application/.........../MyApp
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler […..]
Thread 4 name:
Thread 4 Crashed:
0 libswiftCoreLocation.dylib 0x000000021680b4c8 @objc completion handler block implementation for @escaping @callee_unowned @convention(block) (@unowned CLMonitor) -> () with result type CLMonitor + 44 (<compiler-generated>:0)
1 CoreLocation 0x0000000196cdddd4 __76-[CLMonitorConfiguration vendMonitorWithIdentityAndAuthorizationAttributes:]_block_invoke + 216 (CLMonitorConfiguration.m:195)
2 libdispatch.dylib 0x0000000191138370 _dispatch_call_block_and_release + 32 (init.c:1549)
3 libdispatch.dylib 0x000000019113a0d0 _dispatch_client_callout + 20 (object.m:576)
4 libdispatch.dylib 0x00000001911416d8 _dispatch_lane_serial_drain + 744 (queue.c:3934)
5 libdispatch.dylib 0x00000001911421e0 _dispatch_lane_invoke + 380 (queue.c:4025)
6 libdispatch.dylib 0x000000019114d258 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:7193)
7 libdispatch.dylib 0x000000019114caa4 _dispatch_workloop_worker_thread + 540 (queue.c:6787)
8 libsystem_pthread.dylib 0x0000000211933c7c _pthread_wqthread + 288 (pthread.c:2696)
9 libsystem_pthread.dylib 0x0000000211930488 start_wqthread + 8
Does anyone have similar issue when using CLMonitor?
How can I debug / fix this issue?
Is it an CLMonitor API bug? Should I file a bug report?
I attached a crash log with the details I can share for the moment
So, this crash log is a great example of why I always try to get a full log before trying to diagnose anything. It's very easy to focus on the threads that seem to be the source of the problem without realizing there are other concerns in play.
In this case, my biggest concern is the combination 6 threads and your main thread state:
32 MyMainModule 0x00000001038d4064 +[MyMainModuleInitClass load] + 100 (MyMainModuleInitClass.m:32)
33 libobjc.A.dylib 0x0000000186724714 load_images + 736 (objc-runtime-new.mm:3740)
34 dyld 0x00000001aedfad10 dyld4::RuntimeState::notifyObjCInit(dyld4::Loader const*) + 576 (DyldRuntimeState.cpp:2139)
35 dyld 0x00000001aee33908 dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array&, dyld3::Array&) const + 300 (Loader.cpp:2316)
36 dyld 0x00000001aee338b4 dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array&, dyld3::Array&) const + 216 (Loader.cpp:2309)
37 dyld 0x00000001aee352c8 dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const + 180 (Loader.cpp:2330)
38 dyld 0x00000001aee00c00 dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 412 (Loader.cpp:2326)
39 dyld 0x00000001aedf0280 dyld4::APIs::runAllInitializersForMain() + 296 (DyldAPIs.cpp:4150)
40 dyld 0x00000001aee04d10 dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3404 (dyldMain.cpp:902)
41 dyld 0x00000001aee299f8 dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const + 544 (dyldMain.cpp:1322)
42 dyld 0x00000001aee22cb0 start + 2188 (dyldMain.cpp:1299)
Your app is currently in library load time and has not yet called main. In other words, you've kicked off most of your apps functionality, including initializing system framework like CoreLocation, BEFORE your app has initialized UIKit and started it's event loop.
The systems behavior in this state is basically... undefined. Most of our framework implicitly assume that they're running "in an app" and rely on a variety of implicit configuration/state that comes from that configuration. Lots of things do "work" (which is why your app works at all), but that's basically "accidental", NOT because of any special effort on the frameworks part.
Related to that point, I also noticed that your app crashing very early in a background launch:
Role: Non UI
...
Date/Time: 2024-11-21 14:51:03.5555 +0100
Launch Time: 2024-11-21 14:51:03.1668 +0100
A few questions about this:
-
Is that consistent across all the crash logs you've gotten do some of the logs list a different role? Particularly foreground crashes?
-
Do you what might be triggering that launch (besides CoreLocation)?
The issue here is that the process a daemon uses to launch an app into the background is intended to work something like this:
- The daemon asks the system to launch the app.
- The app is launched.
- The app registers itself with the system early in UIApplicationMain().
- The app connects "back" to the daemon as part of it's normal start up process.
Focusing on point 4, most of our background APIs have some part of the documentation that includes a statement/verbiage similar to this:
"If your app actively receives and processes location updates and terminates, it should restart those APIs upon launch in order to continue receiving updates."
The issue here is that while CoreLocation initiates your app launch, it needs your app to connect BACK to it before it can actually "do" anything with your app. It needs that connection "back" from your app both to deliver events and, more importantly, to keep your app awake to have events delivered to it.
The problem with initializing at library load time (which is what your app is doing) is that you can "flip" the order of 3 & 4. What happens after that point depends entirely on the internal details of locationd and the daemon's that manage app lifetime. In the worst case, locationd is unable to properly "manage" your app because doing so relies on internal "infrastructure" that does actually exist yet (because that infrastructure is initialized in #3).
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware