为什么 Valgrind 在稳定版 1.55.0 中*再次*检测不到内存泄漏?

Why Valgrind does not detect memory leak *again* in stable 1.55.0?

这与 相似但不相同,因为后者已在 Rust 1.32

中解决

一个简单的可重现样本:

# create a new project
cargo new hello && cd hello

cat <<EOT > src/main.rs                                       
fn allocate() {
    let bad_vec = vec![1u8; 1024*1024];
    std::mem::forget(bad_vec);
}

fn main() {
    allocate();
}
EOT

cargo build --release && valgrind target/release/hello

然后我们得到:

   Compiling hello v0.1.0 (/home/cs144/hello)
    Finished release [optimized] target(s) in 0.23s
==16113== Memcheck, a memory error detector
==16113== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16113== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==16113== Command: target/release/hello
==16113== 
==16113== 
==16113== HEAP SUMMARY:
==16113==     in use at exit: 0 bytes in 0 blocks
==16113==   total heap usage: 9 allocs, 9 frees, 2,057 bytes allocated
==16113== 
==16113== All heap blocks were freed -- no leaks are possible
==16113== 
==16113== For lists of detected and suppressed errors, rerun with: -s
==16113== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

请注意,如果我们将 let bad_vec = vec![1u8; 1024*1024];1u8 更改为 0u8,那么我们会像 .

中那样愉快地检测内存错误

因此,我无法使用 Valgrind 检测内存问题(因为我有一些不安全的代码)。

嗯,我明白了...使用 Godbolt,代码编译为空(没有内存分配),可能是因为 Rust 的优化。然而,使用 0u8 代码,它确实编译成某种东西 (__rust_alloc_zeroed),因此在这种情况下确实发生了内存泄漏。

最后我使用类似下面的东西来禁止 Rust 优化泄漏的代码。

    let ptr = Box::leak(Box::new(vec![42; 100]));
    println!("ptr={:?}", ptr)