Closed priconceptions closed 2 years ago
I believe this is a consequence of moving the call to startRunning()
to a background thread, by doing that the execution order isn't guaranteed anymore so if it gets called while configuration changes are happening the crash will happen.
I'm not sure yet what a good fix would be. If we move the call to startRunning()
back to the main thread we'd be blocking it which is also bad.
Here's the full crash report:
OS Version: iOS 15.3.1 (19D52)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 11
Application Specific Information:
*** -[AVCaptureSession startRunning] startRunning may not be called between calls to beginConfiguration and commitConfiguration
Thread 11 Crashed:
0 CoreFoundation 0x30073bd3c <redacted>
1 libobjc.A.dylib 0x32eeac6a4 objc_exception_throw
2 AVFCapture 0x346327690 -[AVCaptureSession startRunning]
3 Wave 0x202d10aa8 thunk for closure
4 libdispatch.dylib 0x3001011a0 _dispatch_call_block_and_release
5 libdispatch.dylib 0x3001021a4 _dispatch_client_callout
6 libdispatch.dylib 0x3000b1564 _dispatch_root_queue_drain
7 libdispatch.dylib 0x3000b1c34 _dispatch_worker_thread2
8 libsystem_pthread.dylib 0x3b5452e44 _pthread_wqthread
9 libsystem_pthread.dylib 0x3b54529ec start_wqthread
Thread 0
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 CoreFoundation 0x3006b0b60 <redacted>
3 CoreFoundation 0x3006b4c48 <redacted>
4 CoreFoundation 0x3006c7e1c CFRunLoopRunSpecific
5 GraphicsServices 0x340e2999c GSEventRunModal
6 UIKitCore 0x305261b8c -[UIApplication _run]
7 UIKitCore 0x304ff7168 UIApplicationMain
8 Wave 0x20298882c main (AcceptLanguageInterceptor.swift:10)
9 <unknown> 0x103170250 <redacted>
Thread 1 name: com.apple.uikit.eventfetch-thread
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 CoreFoundation 0x3006b0b60 <redacted>
3 CoreFoundation 0x3006b4c48 <redacted>
4 CoreFoundation 0x3006c7e1c CFRunLoopRunSpecific
5 Foundation 0x3035433dc <redacted>
6 Foundation 0x303581c4c <redacted>
7 UIKitCore 0x3051df8a8 -[UIEventFetcher threadMain]
8 Foundation 0x30358f8bc <redacted>
9 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 2
0 libsystem_kernel.dylib 0x374a19088 __semwait_signal
1 libsystem_c.dylib 0x3151948dc nanosleep
2 libsystem_c.dylib 0x3151a8288 sleep
3 Wave 0x202e06768 monitorCachedData (SentryCrashCachedData.c:139)
4 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 3 name: SentryCrash Exception Handler (Secondary)
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 libsystem_kernel.dylib 0x374a23ff8 thread_suspend
3 Wave 0x202e02178 handleExceptions (SentryCrashMonitor_MachException.c:258)
4 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 4 name: SentryCrash Exception Handler (Primary)
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 Wave 0x202e021a4 handleExceptions (SentryCrashMonitor_MachException.c:266)
3 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 5 name: io.sentry.anr-tracker
0 libsystem_kernel.dylib 0x374a19088 __semwait_signal
1 libsystem_c.dylib 0x3151948dc nanosleep
2 Foundation 0x3035a13c0 <redacted>
3 Wave 0x202dc0380 -[SentryANRTracker detectANRs] (SentryANRTracker.m:67)
4 Foundation 0x30358f8bc <redacted>
5 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 6 name: AVAudioSession Notify Thread
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 CoreFoundation 0x3006b0b60 <redacted>
3 CoreFoundation 0x3006b4c48 <redacted>
4 CoreFoundation 0x3006c7e1c CFRunLoopRunSpecific
5 AudioSession 0x311ee3d78 CADeprecated::GenericRunLoopThread::Entry
6 AudioSession 0x311eed0a8 CADeprecated::CAPThread::Entry
7 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 7 name: com.apple.NSURLConnectionLoader
0 libsystem_kernel.dylib 0x374a18b10 mach_msg_trap
1 libsystem_kernel.dylib 0x374a19130 mach_msg
2 CoreFoundation 0x3006b0b60 <redacted>
3 CoreFoundation 0x3006b4c48 <redacted>
4 CoreFoundation 0x3006c7e1c CFRunLoopRunSpecific
5 CFNetwork 0x3018a4da4 _CFURLStorageSessionCopyIdentifier
6 Foundation 0x30358f8bc <redacted>
7 libsystem_pthread.dylib 0x3b54543a0 _pthread_start
Thread 8
0 libsystem_kernel.dylib 0x374a190cc __workq_kernreturn
1 libsystem_pthread.dylib 0x3b5452ecc _pthread_wqthread
Thread 9
0 libsystem_kernel.dylib 0x374a190cc __workq_kernreturn
1 libsystem_pthread.dylib 0x3b5452ecc _pthread_wqthread
Thread 10
0 libsystem_kernel.dylib 0x374a190cc __workq_kernreturn
1 libsystem_pthread.dylib 0x3b5452ecc _pthread_wqthread
Thread 11 Crashed:
0 CoreFoundation 0x30073bd3c <redacted>
1 libobjc.A.dylib 0x32eeac6a4 objc_exception_throw
2 AVFCapture 0x346327690 -[AVCaptureSession startRunning]
3 Wave 0x202d10aa8 thunk for closure
4 libdispatch.dylib 0x3001011a0 _dispatch_call_block_and_release
5 libdispatch.dylib 0x3001021a4 _dispatch_client_callout
6 libdispatch.dylib 0x3000b1564 _dispatch_root_queue_drain
7 libdispatch.dylib 0x3000b1c34 _dispatch_worker_thread2
8 libsystem_pthread.dylib 0x3b5452e44 _pthread_wqthread
9 libsystem_pthread.dylib 0x3b54529ec start_wqthread
Thread 12
0 libsystem_platform.dylib 0x3b543b0d0 os_unfair_recursive_lock_lock_with_options$VARIANT$mp
1 libobjc.A.dylib 0x32ee9c8c8 objc_sync_enter
2 AVFCapture 0x3462fc1f4 -[AVCaptureSession _updateCameraCalibrationDataDeliveryEnabledForSourceDevice:]
3 AVFCapture 0x346399c9c -[AVCaptureSession _buildAndRunGraph:]
4 AVFCapture 0x346317f00 -[AVCaptureSession _commitConfiguration]
5 Foundation 0x30355bb28 <redacted>
6 Foundation 0x303548194 <redacted>
7 Foundation 0x30357f4f8 <redacted>
8 AVFCapture 0x346307b5c -[AVCaptureMetadataOutput setMetadataObjectTypes:]
9 Wave 0x202d10a4c CodeScannerView.ScannerViewController.viewDidLoad (ScannerViewController.swift:195)
10 Wave 0x202d10ae0 thunk for closure
11 libdispatch.dylib 0x3001011a0 _dispatch_call_block_and_release
12 libdispatch.dylib 0x3001021a4 _dispatch_client_callout
13 libdispatch.dylib 0x3000a41f8 _dispatch_queue_override_invoke
14 libdispatch.dylib 0x3000b1438 _dispatch_root_queue_drain
15 libdispatch.dylib 0x3000b1c34 _dispatch_worker_thread2
16 libsystem_pthread.dylib 0x3b5452e44 _pthread_wqthread
Thread 13
0 AVFCore 0x311f5818c __destroy_helper_block_e8_32o40o48o
1 libsystem_blocks.dylib 0x3b5341830 _Block_release
2 libdispatch.dylib 0x3001021a4 _dispatch_client_callout
3 libdispatch.dylib 0x3000b04c8 _dispatch_lane_concurrent_drain
4 libdispatch.dylib 0x3000a8c14 _dispatch_lane_invoke$VARIANT$mp
5 libdispatch.dylib 0x3000a40cc _dispatch_queue_override_invoke
6 libdispatch.dylib 0x3000b1438 _dispatch_root_queue_drain
7 libdispatch.dylib 0x3000b1c34 _dispatch_worker_thread2
8 libsystem_pthread.dylib 0x3b5452e44 _pthread_wqthread
Something I found interesting is that thread 12 is in viewDidLoad()
(and hasn't finished its call to commitConfiguration()
) while thread 11 is already calling startRunning()
in viewWillAppear()
. This doesn't make sense to me because I would assume viewWillAppear()
wouldn't start until viewDidLoad()
had finished.
Oh but the related code is wrapped in the requestAccess()
callback, which might happen after viewDidLoad is over.
Ok I'm pretty sure the solution is to do the permission checking somewhere else, the way it was implemented in https://github.com/twostraws/CodeScanner/pull/49 causes the configuration changes to potentially happen during/after we call startRunning.
In our app in particular, we handle the permission logic ourselves and I'd assume that's what every other app that uses this library is doing because there was no logic to handle permissions prior to that PR.
Additionally, that PR doesn't really change behavior based on the permission state. Here, I would expect the block param not to be ignored and the code to look something like this:
AVCaptureDevice.requestAccess(for: .video) { success in
if success {
// something
} else {
// something else
}
With all of that, I think it would be a good idea to revert it so I'm about to submit a revert PR for your consideration.
I can confirm the issue @Jesus. Permission check does not look like a part of this component functionality. Think that reverting #71 is good idea.
That change has been reverted, and another put in its place – hopefully this is improved.
Hi,
I am seeing crashes in production when I updated to the latest version of Code Scanner. I can't seem to reproduce this issue but it's happening to many of our users. Here are some of the breadcrumbs before this issue occurs:
screen: _TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_14NoStyleContext_
screen: _TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_24NavigationColumnModifier__
screen: SwiftUI.NotifyingMulticolumnSplitViewController
screen: _TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_19SidebarStyleContext_
screen: _TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentGS1_VVS_22_VariadicView_Children7ElementVS_24NavigationColumnModifier_GVS_18StyleContextWriterVS_19SidebarStyleContext___
action: UIKeyboardDidHideNotification
screen: _TtCV11CodeScanner15CodeScannerView21ScannerViewController
NSGenericException: *** -[AVCaptureSession startRunning] startRunning may not be called between calls to beginConfiguration and commitConfiguration
Does anyone have any insights on how to fix this issue?