AddressSanitizer:仅在 Release archive 上使用 heap-after-free

AddressSanitizer: heap-use-after-free only on Release archive

我已经为我的 class 创建了一个示例: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 这会导致崩溃?或者有人可以指出我的代码问题?

谢谢!

将 Release 存档的 Optimization Level 更改为与 Debug 相同的 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进行操作,所有的操作都在一个闭包内进行。

添加到@vpoltave 提供的 中,我发现在创建样本缓冲区后使用调度队列曾经给我一个 EXC_BAD_ACCESS 错误,或者如果你打开地址消毒器,那么它会在 com.apple.coremedia.videomediaconverterUse of deallocated memory 中出错。建议将原始数据而不是创建的缓冲区放入队列。对我来说,来源是回调中的基本格式框架。