My app experiencing a rare crash that I am unable to reproduce and am struggling to make progress with:
Thread 0 name:
Thread 0 Crashed:
0 libobjc.A.dylib 0x00000001926c3c20 objc_msgSend + 32 (:-1)
1 Foundation 0x00000001997357b4 __NSThreadPerformPerform + 264 (NSThread.m:1084)
2 CoreFoundation 0x000000019a82b834 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1957)
3 CoreFoundation 0x000000019a82b7c8 __CFRunLoopDoSource0 + 176 (CFRunLoop.c:2001)
4 CoreFoundation 0x000000019a8292f8 __CFRunLoopDoSources0 + 340 (CFRunLoop.c:2046)
5 CoreFoundation 0x000000019a828484 __CFRunLoopRun + 828 (CFRunLoop.c:2955)
6 CoreFoundation 0x000000019a827cd8 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420)
7 GraphicsServices 0x00000001df2751a8 GSEventRunModal + 164 (GSEvent.c:2196)
8 UIKitCore 0x000000019ce61ae8 -[UIApplication _run] + 888 (UIApplication.m:3713)
9 UIKitCore 0x000000019cf15d98 UIApplicationMain + 340 (UIApplication.m:5303)
10 <redacted> 0x000000010287af04 main + 64 (AppDelegate.swift:15)
11 dyld 0x00000001bdfff154 start + 2356 (dyldMain.cpp:1298)
I have done a fair amount of digging, looking at other similar crashes and at this: https://developer.apple.com/forums/thread/92102 but being unable to reproduce is quite limiting.
I found this very similar issue with useful info on finding which function was being called: https://forums.developer.apple.com/forums/thread/67763
But in my case, the x1 (and x2) register values seem to point to an area outside of the ranges in the "Binary Images" section..
I've attached an example of a full crash report (with the app name redacted):
Any help would be greatly appreciated.
Thanks for the response. We think we have a fix for this. It turns out this thread was more directly relevant than we realised: https://forums.developer.apple.com/forums/thread/67763
We found a variant of the crash which mentioned finishPlaying
and attempts to call it on random types, e.g. CAShapeLayer
here, but we also saw __NSDictionaryM
and various others:
-[CAShapeLayer finishedPlaying:]: unrecognized selector sent to instance 0x30073a1e0
1 libobjc.A.dylib 0x172e4 objc_exception_throw
2 CoreFoundation 0x1888c8 +[NSObject(NSObject) _copyDescription]
3 CoreFoundation 0x20b08 ___forwarding___
4 CoreFoundation 0x20430 _CF_forwarding_prep_0
5 Foundation 0xa7e50 __NSThreadPerformPerform
6 CoreFoundation 0x56328 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
7 CoreFoundation 0x562bc __CFRunLoopDoSource0
8 CoreFoundation 0x53e24 __CFRunLoopDoSources0
9 CoreFoundation 0x52fbc __CFRunLoopRun
10 CoreFoundation 0x52830 CFRunLoopRunSpecific
11 GraphicsServices 0x11c4 GSEventRunModal
12 UIKitCore 0x3d2eb0 -[UIApplication _run]
13 UIKitCore 0x4815b4 UIApplicationMain
14 <redacted> 0x74d9c main + 16 (AppDelegate.swift:16)
15 ??? 0x1b7b36ec8 (Missing)
This seems to happen if an AVAudioPlayer
is deallocated the split second it has finished playing.
This is the code we had:
let audioPlayer = try AVAudioPlayer(data: audioData)
audioPlayer.prepareToPlay()
audioPlayer.play(atTime: audioPlayer.deviceCurrentTime + delay)
self.audioPlayer = audioPlayer
It was possible for this to be called just after a previous sound had finished and deallocate the current self.audioPlayer (and we have a large enough user base (in the millions) for this to happen in the wild).
Our fix was to add this to stop any existing audio player before reassigning it and we have not see the crash since we released this yesterday:
+ self.audioPlayer?.stop()
let audioPlayer = try AVAudioPlayer(data: audioData)
audioPlayer.prepareToPlay()
audioPlayer.play(atTime: audioPlayer.deviceCurrentTime + delay)
self.audioPlayer = audioPlayer
Easy to reproduce
Incidentally, it is pretty trivial to force this crash to happen, if it's something that could be worked on and prevented by Apple:
let audioPlayer = try AVAudioPlayer(data: audioData)
audioPlayer.prepareToPlay()
audioPlayer.play(atTime: audioPlayer.deviceCurrentTime + delay)
self.audioPlayer = audioPlayer
while audioPlayer.isPlaying {
// Wait
}
self.audioPlayer = nil // deallocation immediately after isPlaying becomes false causes crash