AddressSanitizer:heap-use-after-free 仅在发布存档上

Posted

技术标签:

【中文标题】AddressSanitizer:heap-use-after-free 仅在发布存档上【英文标题】:AddressSanitizer: heap-use-after-free only on Release archive 【发布时间】:2020-11-21 14:43:47 【问题描述】:

我已经为我的班级创建了一个示例:https://github.com/ChoadPet/H.264-Decoding

当我使用DEBUG 配置构建我的应用程序时,一切正常正常,但是当我归档RELEASE 时,它在这条线上崩溃了:

let status = VTDecompressionSessionDecodeFrame(session,
                                               sampleBuffer: sampleBuffer,
                                               flags: defaultDecodeFlags,
                                               frameRefcon: nil,
                                               infoFlagsOut: nil)

使用Address Sanitizer 启用我收到此错误: Thread 9: Use of deallocated memory

SUMMARY: AddressSanitizer: heap-use-after-free
(.../Frameworks/libclang_rt.asan_ios_dynamic.dylib:arm64+0x1a1f4) in wrap_memmove
...
(if you need more crash info, let me know)

没有:Thread 12: EXC_BAD_ACCESS (code=1, address=0x107dd0020)


我知道有一些内存已被释放并通过VTDecompressionSessionDecodeFrame 方法访问,但我找不到任何十六进制地址,我不明白这如何与DEBUG 完美配合构建。 在这个方法之前,sessionsampleBuffer已经成功创建(初始化)了。

是否有一些我可以更改为DEBUG configuration 的项目设置会导致崩溃?或者有人可以指出我的代码问题?

谢谢!

【问题讨论】:

如果sampleBuffer 是可选的,也许您可​​以在使用前使用guard 将其解包? 【参考方案1】:

将发布存档的Optimization Level 更改为与调试相同的No Optimization[-Onone] 隐藏问题,但更改构建配置不是解决此类问题的正确方法。此外,问题并不完全在sampleBuffer 中。问题出在blockBufferOut 参数中,稍后会进入sampleBuffer。我会更新 repo 源代码,让社区可以清楚地看到变化。

所以我之前有这个逻辑:

// 1. Creating blockBuffer from `bufferPointer`
localFrame.withUnsafeMutableBufferPointer  bufferPointer in
   // I should write everything in this body,
   // since bufferPointer would be released after the closure
   // and so, it will be released from bufferBlock


// 2. I called this method, which is creating `sampleBuffer`
CMSampleBufferCreateReady

// 3. I called this method, which is decode frame with session and sampleBuffer 
VTDecompressionSessionDecodeFrame

/* 
and on this line, it crashes with EXC_BAD_ACCESS, 
because the sample wasn't valid anymore, because 
on step 1, bufferPointer only valid inside body closure, 
so it's release after block when I created sampleBuffer
and later decode it.


This is even pointed by documentation:

Parameters

body
Closure with an UnsafeMutableBufferPointer parameter that points to the
contiguous storage for the array. If no such storage exists, it is created. If
the body has a return value, that value is also used as the return value for the
withUnsafeMutableBufferPointer(_:) method. The pointer argument is valid only for
the duration of the method’s execution.
*/

总结:如果对bufferPointer进行操作,所有操作都在闭包内完成。

【讨论】:

【参考方案2】:

添加到@vpoltave 提供的answer,我发现在创建样本缓冲区后使用调度队列会给我一个EXC_BAD_ACCESS 错误,或者如果您打开地址清理器,那么它会在@987654323 中出错@ 与Use of deallocated memory。建议将原始数据排入队列,而不是创建的缓冲区。对我来说,来源是回调中的基本格式的框架。

【讨论】:

以上是关于AddressSanitizer:heap-use-after-free 仅在发布存档上的主要内容,如果未能解决你的问题,请参考以下文章

AddressSanitizer 页面

使用AddressSanitizer做内存分析

AddressSanitizer:地址上的堆缓冲区溢出

addressSanitizer:地址上的堆缓冲区溢出

是否可以将 AddressSanitizer 和 ThreadSanitizer 组合成一个版本?

Xcode7 新特性 AddressSanitizer