Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Valgrind not detect a memory leak in a Rust program using nightly 1.29.0?

Tags:

rust

valgrind

I'm trying to detect a memory leak in a Rust program using Valgrind following this blog post. My source code is simply:

#![feature(alloc_system)]
extern crate alloc_system;

use std::mem;

fn allocate() {
    let bad_vec = vec![0u8; 1024*1024];
    mem::forget(bad_vec);
}

fn main() {
    allocate();
}

I expect the call to mem::forget() to generate a memory leak that Valgrind would be able to pick up on. However, when I run Valgrind, it reports that no leaks are possible:

[memtest]> cargo run
   Compiling memtest v0.1.0 (file:///home/icarruthers/memtest)
    Finished dev [unoptimized + debuginfo] target(s) in 0.28s
     Running `target/debug/memtest`
[memtest]> valgrind target/debug/memtest
==18808== Memcheck, a memory error detector
==18808== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18808== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18808== Command: target/debug/memtest
==18808== 
==18808== 
==18808== HEAP SUMMARY:
==18808==     in use at exit: 0 bytes in 0 blocks
==18808==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==18808== 
==18808== All heap blocks were freed -- no leaks are possible
==18808== 
==18808== For counts of detected and suppressed errors, rerun with: -v
==18808== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

I am upgraded to the latest nightly (1.29.0-nightly (6a1c0637c 2018-07-23)).

What am I missing?

like image 640
Isaac Avatar asked Jul 25 '18 00:07

Isaac


People also ask

How does Valgrind detect memory leaks?

Detecting memory leaks with Valgrind MemcheckMemcheck tracks all memory reads, writes, allocations, and deallocations in a C or C++ program. The tool can detect many different memory errors. For instance, it detects reads or writes before or after allocated memory blocks.

Does Valgrind work with Rust?

Valgrind Memcheck is a tool for detecting memory-usage problems such as leaks, invalid memory access, incorrect freeing, and referencing undefined values. Although Valgrind Memcheck primarily targets C/C++, you can also use it for Rust code on Linux and macOS.

Is it possible to leak memory in Rust?

Isn't Rust supposed to be “safe?” It turns out that, according to Rust's rules, leaking memory is completely safe! In fact, we can purposely leak as much memory as we want using the function std::mem::forget .

How do you run a Valgrind memory leak?

To run Valgrind, pass the executable as an argument (along with any parameters to the program). The flags are, in short: --leak-check=full : "each individual leak will be shown in detail" --show-leak-kinds=all : Show all of "definite, indirect, possible, reachable" leak kinds in the "full" report.


1 Answers

Rust 1.32

As of Rust 1.32, the default allocator for an executable is now the system allocator, so you don't need to set anything by default.

Previous versions

You aren't using the global allocator setting correctly. This is a nightly feature, which means that it's prone to change at any time. Your blog post is out of date.

Check the module docs for std::alloc to see the correct usage:

#![feature(alloc_system)]
extern crate alloc_system;

#[global_allocator]
static GLOBAL: alloc_system::System = alloc_system::System;

use std::mem;

fn allocate() {
    let bad_vec = vec![0u8; 1024*1024];
    mem::forget(bad_vec);
}

fn main() {
    allocate();
}
root@3fb431791293:/tmp/vg# valgrind target/debug/vg
==6326== Memcheck, a memory error detector
==6326== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6326== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6326== Command: target/debug/vg
==6326==
==6326==
==6326== HEAP SUMMARY:
==6326==     in use at exit: 1,048,576 bytes in 1 blocks
==6326==   total heap usage: 12 allocs, 11 frees, 1,050,753 bytes allocated
==6326==
==6326== LEAK SUMMARY:
==6326==    definitely lost: 1,048,576 bytes in 1 blocks
==6326==    indirectly lost: 0 bytes in 0 blocks
==6326==      possibly lost: 0 bytes in 0 blocks
==6326==    still reachable: 0 bytes in 0 blocks
==6326==         suppressed: 0 bytes in 0 blocks
==6326== Rerun with --leak-check=full to see details of leaked memory
==6326==
==6326== For counts of detected and suppressed errors, rerun with: -v
==6326== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
like image 66
Shepmaster Avatar answered Oct 14 '22 02:10

Shepmaster