Reputation: 3671
I am experiencing a very consistent crash in my app that was introduced with iOS 14.2. We are using Crashlytics to track crashes and can confirm 100% of these new crashes are on 14.2 and above. I have also been able to recreate on 14.2 and the current second beta release of 14.3
I cannot recreate it on 14.1. Also, these features have been live for quite a while and no changes have been made to the features themselves in the last several iOS major/minor versions.
The specific error is:
error: memory read failed for 0x0:
com.apple.audio.toolbox.AUScheduledParameterRefresher (20): EXC_BAD_ACCESS (code=1, address=0x0)
The gist of the crash:
• I have a playback/recording mechanism in our application. This can either be playing back a single audio track or playing back multiple tracks at once.
• This only happens when I have audio effects enabled on the tracks (i.e. reverb, compression, etc.). I am using the AVAudioUnitEffect library to implement the audio effects on the tracks being played back.
• This happens when a user manipulate settings (i.e. volume or gain) on the effects and then try to do another action afterwards.
I cannot find any documentation on AUScheduledParameterRefresher. I have also extended the scope of my search in XCode to include the entire 14.2 SDK but there's no reference to it in there as well.
Based on the EXC_BAD_ACCESS error, my guess is that some piece of the process gets deallocated from memory and when the code goes to alter the settings on the audio effect it no longer exists. I turned on Zombies to try to capture any deallocated objects in Instruments but it did not turn anything up.
I also downloaded the iOS 14.1 SDK and ran a comparison on the audio frameworks (AudioToolbox, AVFoundation, etc.) to see if anything significant had changed but it doesn't appear so so it could be a bit lower level than even these libraries.
We have created a minimal app and posted it to GitHub to display the issue: https://github.com/audiobridge/iOSCrashDemo
This is stripped down to just building the effects and the parameters and the app crashes when you hit the button that initializes this.
Using the app seems to infer that the issue lies in the AVAudioUnitEQ. If you remove that from the chain, the bug/crash is gone. It would seem that something gets scheduled to reference the AVAudioUnitEQ in the 'future' after the function already destroys the effect since it is no longer needed.
I'm having trouble getting any deeper into this issue. Any help would be greatly appreciated. Thank you!
For reference, here is a stack trace from Crashlytics on the thread where the crash occurs:
Crashed: com.apple.audio.toolbox.AUScheduledParameterRefresher
EXC_BAD_ACCESS KERN_PROTECTION_FAILURE 0x00000001dd778040
0 ??? 0x1dd778040 (Missing)
1 AudioToolboxCore 0x196846638 AudioUnitGetParameter + 52
2 AudioToolboxCore 0x1967d8200 43-[AUAudioUnitV2Bridge _createParameterTree]_block_invoke.125 + 112
3 AudioToolboxCore 0x196788284 -[AUParameter _internalValue] + 252
4 AudioToolboxCore 0x19678ba28 20-[AUParameter value]_block_invoke + 32
5 libdispatch.dylib 0x186bce280 _dispatch_client_callout + 16
6 libdispatch.dylib 0x186bb10ec _dispatch_lane_barrier_sync_invoke_and_complete + 56
7 AudioToolboxCore 0x196788408 -[AUParameter value] + 244
8 AudioToolboxCore 0x1967daea0 parameterNodesEqual(AUParameterNode*, AUParameterNode*, std::1::vector<unsigned long long, std::1::allocator<unsigned long long> >&) + 1180
9 AudioToolboxCore 0x1967dac94 parameterNodesEqual(AUParameterNode*, AUParameterNode*, std::1::vector<unsigned long long, std::1::allocator<unsigned long long> >&) + 656
10 AudioToolboxCore 0x1967dac94 parameterNodesEqual(AUParameterNode*, AUParameterNode*, std::1::vector<unsigned long long, std::1::allocator<unsigned long long> >&) + 656
11 AudioToolboxCore 0x1967da9dc invocation function for block in void applesauce::dispatch::v1::sync_impl<-[AUAudioUnitV2Bridge _buildNewParameterTree]::$_0>(NSObject<OS_dispatch_queue>*, -[AUAudioUnitV2Bridge _buildNewParameterTree]::$_0&&, std::1::integral_constant<bool, true>) + 104
12 libdispatch.dylib 0x186bce280 _dispatch_client_callout + 16
13 libdispatch.dylib 0x186bb10ec _dispatch_lane_barrier_sync_invoke_and_complete + 56
14 AudioToolboxCore 0x1967d4034 -[AUAudioUnitV2Bridge _buildNewParameterTree] + 140
15 AudioToolboxCore 0x1967d4238 -[AUAudioUnitV2Bridge _invalidateParameterTree:] + 124
16 AudioToolboxCore 0x1967da820 caulk::concurrent::details::message_call<ParameterListPropertyListener(void*, OpaqueAudioComponentInstance*, unsigned int, unsigned int, unsigned int)::$_5>::perform() + 52
17 AudioToolboxCore 0x1967da7bc caulk::concurrent::details::rt_message_call<ParameterListPropertyListener(void*, OpaqueAudioComponentInstance*, unsigned int, unsigned int, unsigned int)::$_5>::perform() + 24
18 caulk 0x1c89c2280 caulk::concurrent::details::messenger_servicer::check_dequeue() + 104
19 caulk 0x1c89c1f34 caulk::concurrent::details::worker_thread::run() + 56
20 caulk 0x1c89c20bc void* caulk::thread_proxy<std::1::tuple<caulk::thread::attributes, void (caulk::concurrent::details::worker_thread::*)(), std::__1::tuple<caulk::concurrent::details::worker_thread*> > >(void*) + 56
21 libsystem_pthread.dylib 0x1cd5a0b3c _pthread_start + 288
22 libsystem_pthread.dylib 0x1cd5a5880 thread_start + 8
Upvotes: 3
Views: 666
Reputation: 54445
Based on your sample code project, it's possible to prevent the crash by moving the definition of eqEffect to a class property…
class ViewController: UIViewController {
let eqEffect = AVAudioUnitEQ(numberOfBands: 3)
…and updating all of the references createEffects
to point at that. For example…
let lowFilterParams = self.eqEffect.bands[0]
However, whilst this will prevent the crash (which is presumably due to the AVAudioUnitEQ being deallocated when the method that configures it completes) I'm not sure if this will result in the behaviour you're expecting in your actual app, as I don't know whether the AVAudioUnitEQ is likely to be released whilst it's still being used. (Its presence as a property of the view controller in your sample code means that it'll always be available.)
Upvotes: 1