Crash with AVAudioPlayer

Hello


I would appreciate any help with a certain crash. It is not something I can reproduce locally (probably met it once in a couple years), but it is top crash for all my projects in XCode Organizer. Like 10 times more frequent than #2 crash.


The crash itself is this:

Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Exception Subtype: KERN_INVALID_ADDRESS at 0x000000026d6f7b76

VM Region Info: 0x26d6f7b76 is not in any region. Bytes after previous region: 2170747767 Bytes before following region: 311461002


Thread 0 name:

Thread 0 Crashed:

0 libobjc.A.dylib 0x00000001a8848d7c objc_msgSend + 28

1 Foundation 0x00000001aa11442c __NSThreadPerformPerform + 336 (NSThread.m:1259)

2 CoreFoundation 0x00000001a95f11f0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 (CFRunLoop.c:1980)

3 CoreFoundation 0x00000001a95f1170 __CFRunLoopDoSource0 + 88 (CFRunLoop.c:2015)

4 CoreFoundation 0x00000001a95f0a54 __CFRunLoopDoSources0 + 176 (CFRunLoop.c:2051)

5 CoreFoundation 0x00000001a95eb920 __CFRunLoopRun + 1040 (CFRunLoop.c:2922)

6 CoreFoundation 0x00000001a95eb1f0 CFRunLoopRunSpecific + 436 (CFRunLoop.c:3247)

7 GraphicsServices 0x00000001ab864584 GSEventRunModal + 100 (GSEvent.c:2245)

8 UIKitCore 0x00000001d65374c0 UIApplicationMain + 212 (UIApplication.m:4347)

9 Euchre 0x00000001004597a8 main + 120744 (AppDelegate.swift:14)

10 libdyld.dylib 0x00000001a90aabb4 start + 4


Similarly to https://forums.developer.apple.com/thread/67763 and https://stackoverflow.com/questions/49864354/avfaudio-crash-on-performselectorwithobjectfinishedplaying, I found that it crashes on performSelector:withObject:finishedPlaying.


I understand, that an easy way to get such crash is by setting AVAudioPlayer.delegate to some object, then nil out other references to that object (I use Swift). When sound stops, the delegate's method will be called on already cleared object. The problem is that while I extensively use AVAudioPlayers to play sounds, I never set their delegates, only checking isPlaying sometimes.


Any thoughts or ideas?


I also want to mention another crash just for a chance that it will help. I got only one such crash, but it seems related. It looks like there is some delegate "living" in AVAudioPlayer.mm file???


OS Version: iPhone OS 11.4.1 (15G77)

Baseband Version: 6.80.00

Report Version: 104



Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Exception Subtype: KERN_INVALID_ADDRESS at 0x001d000000000048

VM Region Info: 0x1d000000000048 is not in any region. Bytes after previous region: 8162766271545417

REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL

MALLOC_NANO (reserved) 00000001d8000000-00000001e0000000 [128.0M] rw-/rwx SM=NUL ...(unallocated)

--->

UNUSED SPACE AT END



Termination Signal: Segmentation fault: 11

Termination Reason: Namespace SIGNAL, Code 0xb

Terminating Process: exc handler [0]

Triggered by Thread: 0



Thread 0 name:

Thread 0 Crashed:

0 AVFAudio 0x00000001876544f8 -[AVAudioPlayer stop] + 28 (AVAudioPlayer.mm:495)

1 AVFAudio 0x00000001876534c0 -[AVAudioPlayer(AVAudioPlayerPriv) finishedPlaying:] + 40 (AVAudioPlayer.mm:265)

2 Foundation 0x000000018274a0ec __NSThreadPerformPerform + 340 (NSThread.m:1265)

3 CoreFoundation 0x0000000181ca7404 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 (CFRunLoop.c:1982)

4 CoreFoundation 0x0000000181ca6c2c __CFRunLoopDoSources0 + 276 (CFRunLoop.c:2017)

5 CoreFoundation 0x0000000181ca479c __CFRunLoopRun + 1204 (CFRunLoop.c:2920)

6 CoreFoundation 0x0000000181bc4da8 CFRunLoopRunSpecific + 552 (CFRunLoop.c:3245)

7 GraphicsServices 0x0000000183baa020 GSEventRunModal + 100 (GSEvent.c:2245)

8 UIKit 0x000000018bbe4758 UIApplicationMain + 236 (UIApplication.m:3965)

9 Hearts 0x0000000100806320 main + 74528 (AppDelegate.swift:14)

10 libdyld.dylib 0x0000000181655fc0 start + 4

Exactly the same crash, exactly the same stack trace here in 2023. Did anyone find the solution? What I've found - if the sound is very short (<< than 1 sec) it reproduces more frequently. Also, crash is always on main thread, while I NEVER do anything with AVFoundation other than dedicated serial queue

@iago849 I finally resolved it a couple months ago. I'll post a solution later today.

Ok, let me share my findings (no matter how scarce), may be they will help someone. I did not use AVAudioPlayer's delegate in my code, but I had a collection of sounds which were supposedly playing and once in a while I iterated over that collection and deleted sounds with false isPlaying field. It resulted in a crash mentioned above, though it was extremely rare. Your situation may look completely different (like having a single AVAudioPlayer which gets deleted together with encompassing class), but the effect is probably the same.

What I changed to finally get rid of the bug: I made AVAudioPlayerDelegate, which deleted the sound that just finished playing.

My theory is the following. The sound playing code runs on another thread and when it finishes, it sets isPlaying to false (or whatever results in it returning false) and tries to call the delegate's finishedPlaying on UI thread, which involves some minor delay. Now what happens if you delete the AVAudioPlayer between those 2 events is probably what results in attempt to access the deleted player's delegate?.finishedPlaying.

It is just a speculative guesswork, but it seems to fit the observed results: the crash, why it is so difficult to reproduce and why my changes fixed it.

Crash with AVAudioPlayer
 
 
Q