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
完美配合构建。
在这个方法之前,session
和sampleBuffer
已经成功创建(初始化)了。
是否有一些我可以更改为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 仅在发布存档上的主要内容,如果未能解决你的问题,请参考以下文章