Rust库Box对象在C中疑似自动释放?实为ASAN检测bug
Rust Box与C交互时ASAN的N-1次泄漏报告bug
我发现一个异常现象:Rust的Box<Context>(对应C中的struct Context *)在main函数退出时,ASAN会表现出自动释放一个实例的假象。
复现代码与环境
Rust库代码(lib.rs)
编译为/home/codes/libspeakdet.so,使用cargo build编译:
pub struct Context { pub sim: f32 } #[no_mangle] pub extern "C" fn make_context() -> Box<Context> { Box::new(Context { sim: 0.2733f32 }) } #[no_mangle] pub extern "C" fn drop_context(_ctx: Option<Box<Context>>) {}
C测试程序(test.c)
编译命令:cc -fsanitize=address -fno-omit-frame-pointer -o test -g test.c /home/codes/libspeakdet.so
struct Context *make_context(); void drop_context(struct Context *ctx); int main(int argc, char *argv[]) { struct Context *ctx; ctx = make_context(); //drop_context(ctx); ctx = make_context(); return 0; }
现象描述
- 当注释掉
drop_context(ctx);时,运行test程序,ASAN报告仅1次直接泄漏(4字节):
44143ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4 byte(s) in 1 object(s) allocated from:
...
- 取消注释
drop_context(ctx);则无泄漏报告。 - 调用N次
make_context,ASAN始终仅报告N-1次直接泄漏。
问题分析与结论
最初疑惑:Rust的所有权机制是语言层面的,C程序本身没有自动释放Rust分配内存的逻辑,为何会出现最后一个实例被“自动释放”的假象?
经过多组验证实验(修改ctx赋值逻辑、对比纯C库的泄漏报告、调整Context结构体大小等),最终确认:这种N-1次泄漏的报告行为是ASAN针对Rust代码的检测bug,实际所有未调用drop_context的实例都存在内存泄漏,ASAN错误地漏报了最后一个实例的泄漏。
内容的提问来源于stack exchange,提问作者Catau
相关产品推荐
相关产品推荐

