2

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).

Herohtar
  • 5,347
  • 4
  • 31
  • 41
ch271828n
  • 15,854
  • 5
  • 53
  • 88

1 Answers1

3

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)
ch271828n
  • 15,854
  • 5
  • 53
  • 88
  • Is this intended to be an edit to your question? It certainly doesn't make sense as an answer. – Maximilian Burszley Oct 18 '21 at 10:08
  • 1
    @MaximilianBurszley It is indeed the answer. Question is, why leak is not detected? Answer is, the code that deliberately causes the leak **is optimized away**, so of course not detected... – ch271828n Oct 18 '21 at 10:22
  • 1
    @MaximilianBurszley I figure out the answer after I post the question, and I do not want to delete the question in case anyone has same problem as me. So I self-answered it. – ch271828n Oct 18 '21 at 10:22
  • If there is no leak to detect then "why is the leak not detected?" isn't even a valid question. Valgrind correctly identifies the leaks when they are actually present in the compiled binary (both in the case of `std::mem::forget()` and `Box::leak()`). If the code is modified so that the allocated memory is actually used (eg, adding a `println!("{:?}", bad_vec)`) then it does not get optimized away and the leak is detected. – Herohtar Oct 18 '21 at 21:32
  • 1
    @Herohtar I agree - but I did not recognize that *when* I asked the question. – ch271828n Oct 18 '21 at 22:48