iOS 14.2 中引入 AudioToolback 崩溃

Posted

技术标签:

【中文标题】iOS 14.2 中引入 AudioToolback 崩溃【英文标题】:AudioToolback Crash Introduced in iOS 14.2 【发布时间】:2020-12-04 02:40:04 【问题描述】:

我在 ios 14.2 中引入的应用程序中经常遇到崩溃。我们正在使用 Crashlytics 跟踪崩溃,并且可以确认 100% 的这些新崩溃发生在 14.2 及更高版本上。我还能够在 14.2 和 14.3 的当前第二个 beta 版本上重新创建

我无法在 14.1 上重新创建它。此外,这些功能已经上线了很长一段时间,并且在最近的几个 iOS 主要/次要版本中没有对功能本身进行任何更改。

具体错误是:

error: memory read failed for 0x0:

com.apple.audio.toolbox.AUScheduledParameterRefresher (20): EXC_BAD_ACCESS (code=1, address=0x0)

崩溃的要点:

• 我的应用程序中有播放/录制机制。这可以是播放单个音轨或一次播放多个音轨。

• 仅当我在轨道上启用了音频效果(即混响、压缩等)时才会发生这种情况。我正在使用 AVAudioUnitEffect 库来实现正在播放的曲目上的音频效果。

• 当用户操作效果器的设置(即音量或增益)然后尝试执行其他操作时,会发生这种情况。

我在 AUScheduledParameterRefresher 上找不到任何文档。我还在 XCode 中扩展了我的搜索范围,以包括整个 14.2 SDK,但其中也没有对它的引用。

基于 EXC_BAD_ACCESS 错误,我的猜测是进程的某些部分从内存中释放,当代码更改音频效果的设置时,它不再存在。我打开了 Zombies 以尝试在 Instruments 中捕获任何已释放的对象,但没有任何结果。

我还下载了 iOS 14.1 SDK 并对音频框架(AudioToolbox、AVFoundation 等)进行了比较,以查看是否有任何重大变化但没有出现,因此它可能比甚至更低的级别这些库。


我们创建了一个最小的应用程序并将其发布到 GitHub 以显示问题: https://github.com/audiobridge/iOSCrashDemo

这被简化为仅构建效果和参数,当您点击初始化它的按钮时应用程序崩溃。

使用该应用程序似乎可以推断出问题在于 AVAudioUnitEQ。如果您从链中删除它,则错误/崩溃就消失了。在函数已经破坏效果之后,似乎有一些东西被安排在“未来”引用 AVAudioUnitEQ,因为它不再需要了。


我无法深入了解这个问题。任何帮助将不胜感激。谢谢!

作为参考,这里是 Crashlytics 在发生崩溃的线程上的堆栈跟踪:

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

【问题讨论】:

你能提供一个最小的应用程序来重现错误吗? @mr.fixit 我们正在为此努力。还向 Apple 提交了代码级提交票证。构建完成后将在此处共享一个最小应用程序。谢谢! @mr.fixit 我刚刚在描述中添加了一个指向最小应用程序的链接。谢谢! 我没有什么可以给你的,除非我在运行你的项目时打开了“线程清理器”,我没有崩溃,并且在控制台中:2020-12-07 22:39:58.782989 -0500 CrashDemo[57765:836917] [i-aa] AUAudioUnitV2Bridge.mm:1256:-[AUAudioUnitV2Bridge _createParameterTree]_block_invoke: AudioGetParameter 0 (0/0): err -10877. 【参考方案1】:

根据您的示例代码项目,可以通过将 eqEffect 的定义移动到类属性来防止崩溃……

class ViewController: UIViewController 

    let eqEffect = AVAudioUnitEQ(numberOfBands: 3)

...并更新所有引用 createEffects 以指向它。比如……

let lowFilterParams = self.eqEffect.bands[0]

但是,虽然这将防止崩溃(这可能是 由于 AVAudioUnitEQ 在配置它的方法完成时被释放)我不确定这是否会导致您的行为重新期待您的 实际 应用程序,因为我不知道 AVAudioUnitEQ 是否有可能在仍在使用时发布。 (它作为示例代码中视图控制器的属性存在意味着它始终可用。)

【讨论】:

感谢您的更新。你是对的;它解决了测试应用程序中的问题,但正如您所预测的那样,它并不像我们应用程序中的实现那么简单。我们已向 Apple 提交了一个官方错误,因为该错误似乎在 iOS 中更深。 @MillerMedia 感兴趣的是,AVAudioUnitEQ 是在您的主应用程序内存中的对象中,还是超出范围并自动释放?

以上是关于iOS 14.2 中引入 AudioToolback 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS 14.2 中的 SwiftUI PageTabView 性能问题滞后

iOS 14.2,UIKit 编程标题未显示

在 Safari iOS 14.2 上自动播放视频 HTML

iOS14.2 SwiftUI PageTabView 会多次调用 ChildView onAppear 方法

苹果 iOS 14.2 正式发布!新增 117 个 Emoji,还有这 7 个变化值得关注

苹果 iOS 14.2 正式发布!新增 117 个 Emoji,还有这 7 个变化值得关注