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

Viewed 216

This is similar but not the same as Why does Valgrind not detect a memory leak in a Rust program using nightly 1.29.0? since that one was solved in Rust 1.32

A simple reproducible sample:

# 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

Then we get:

   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)

Notice that, if we change let bad_vec = vec![1u8; 1024*1024];'s 1u8 to 0u8, then we happily detect memory error as in the old question.

Thus, I cannot use Valgrind to detect memory problems (since I have some unsafe code).

1 Answers

Well I see... Using Godbolt, the code compiles to nothing (no memory allocations), probably because of Rust's optimizations. However, using the 0u8 code, it indeed compiles to something (__rust_alloc_zeroed), thus the memory leak really happens in that case.

Finally I use something like the following to forbid rust from optimizing out the leaky code.

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