为什么 Valgrind 没有显示 Rust 程序的分配?
Why does Valgrind show no allocations for a Rust program?
我正在学习 Rust,我正在玩 Box
,所以我尝试用 valgrind
检查泄漏,但它显示堆上没有分配:
$ rustc -C opt-level=0 raii.rs
$ valgrind ./raii
==3850== Memcheck, a memory error detector
==3850== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3850== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3850== Command: ./raii
==3850==
5
Changed:10
==3850==
==3850== HEAP SUMMARY:
==3850== in use at exit: 0 bytes in 0 blocks
==3850== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3850==
==3850== All heap blocks were freed -- no leaks are possible
==3850==
==3850== For counts of detected and suppressed errors, rerun with: -v
==3850== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
valgrind --leak-check=full ./raii
显示完全相同的结果。
这是 Rust 代码:
fn main() {
let mut _box2 = Box::new(5i32);
println!("{}", _box2);
*_box2 = 10i32;
println!("Changed:{}", _box2);
{
let _box3 = Box::new(4i32);
}
}
一些其他信息:
$ rustc -V
rustc 1.8.0 (db2939409 2016-04-11)
$ valgrind --version
valgrind-3.10.1
$ uname -a
Linux 3.19.0-59-generic #65~14.04.1-Ubuntu SMP Tue Apr 19 18:57:09 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
这是为什么?我认为 Box
在堆上分配变量。此外,this example 显示几乎相同的代码,而 Valgrind 在那里显示分配。
如果我添加以下代码:
let _stack = (1u64, 2u64, 3u64);
let _heap = Box::new((4u64, 5u64, 6u64));
println!("Memory used by stack: {} bytes", std::mem::size_of_val(&_stack));
println!("Memory used by heap: {} bytes", std::mem::size_of_val(&_heap));
它打印的正是我所期望的:
$ ./raii
Memory used by stack: 24 bytes
Memory used by heap: 8 bytes
- 在第二种情况下,元组被放在堆上,一个指针(8字节)被压入堆栈。
- 在第一种情况下,元组是放在堆栈上的,所以需要 24 个字节。
Valgrind 似乎能够计算来自其他程序的堆分配:
$ valgrind echo "test"
==4575== Memcheck, a memory error detector
==4575== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4575== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4575== Command: echo test
==4575==
test
==4575==
==4575== HEAP SUMMARY:
==4575== in use at exit: 0 bytes in 0 blocks
==4575== total heap usage: 30 allocs, 30 frees, 3,681 bytes allocated
==4575==
==4575== All heap blocks were freed -- no leaks are possible
==4575==
==4575== For counts of detected and suppressed errors, rerun with: -v
==4575== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
生锈 1.32
从 Rust 1.32 开始,可执行文件的 默认分配器 是 now the system allocator,因此默认情况下您不需要设置任何内容。
以前的版本
Rust 在构建二进制文件时使用 jemalloc 作为分配器。目前编译 jemalloc 的方式 does not contain the Valgrind hooks needed.
如果您需要使用 Valgrind 跟踪分配的能力,并且您使用的是 nightly Rust,则可以切换到系统分配器。
另请参阅:
我正在学习 Rust,我正在玩 Box
,所以我尝试用 valgrind
检查泄漏,但它显示堆上没有分配:
$ rustc -C opt-level=0 raii.rs
$ valgrind ./raii
==3850== Memcheck, a memory error detector
==3850== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3850== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3850== Command: ./raii
==3850==
5
Changed:10
==3850==
==3850== HEAP SUMMARY:
==3850== in use at exit: 0 bytes in 0 blocks
==3850== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3850==
==3850== All heap blocks were freed -- no leaks are possible
==3850==
==3850== For counts of detected and suppressed errors, rerun with: -v
==3850== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
valgrind --leak-check=full ./raii
显示完全相同的结果。
这是 Rust 代码:
fn main() {
let mut _box2 = Box::new(5i32);
println!("{}", _box2);
*_box2 = 10i32;
println!("Changed:{}", _box2);
{
let _box3 = Box::new(4i32);
}
}
一些其他信息:
$ rustc -V
rustc 1.8.0 (db2939409 2016-04-11)
$ valgrind --version
valgrind-3.10.1
$ uname -a
Linux 3.19.0-59-generic #65~14.04.1-Ubuntu SMP Tue Apr 19 18:57:09 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
这是为什么?我认为 Box
在堆上分配变量。此外,this example 显示几乎相同的代码,而 Valgrind 在那里显示分配。
如果我添加以下代码:
let _stack = (1u64, 2u64, 3u64);
let _heap = Box::new((4u64, 5u64, 6u64));
println!("Memory used by stack: {} bytes", std::mem::size_of_val(&_stack));
println!("Memory used by heap: {} bytes", std::mem::size_of_val(&_heap));
它打印的正是我所期望的:
$ ./raii
Memory used by stack: 24 bytes
Memory used by heap: 8 bytes
- 在第二种情况下,元组被放在堆上,一个指针(8字节)被压入堆栈。
- 在第一种情况下,元组是放在堆栈上的,所以需要 24 个字节。
Valgrind 似乎能够计算来自其他程序的堆分配:
$ valgrind echo "test"
==4575== Memcheck, a memory error detector
==4575== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4575== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4575== Command: echo test
==4575==
test
==4575==
==4575== HEAP SUMMARY:
==4575== in use at exit: 0 bytes in 0 blocks
==4575== total heap usage: 30 allocs, 30 frees, 3,681 bytes allocated
==4575==
==4575== All heap blocks were freed -- no leaks are possible
==4575==
==4575== For counts of detected and suppressed errors, rerun with: -v
==4575== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
生锈 1.32
从 Rust 1.32 开始,可执行文件的 默认分配器 是 now the system allocator,因此默认情况下您不需要设置任何内容。
以前的版本
Rust 在构建二进制文件时使用 jemalloc 作为分配器。目前编译 jemalloc 的方式 does not contain the Valgrind hooks needed.
如果您需要使用 Valgrind 跟踪分配的能力,并且您使用的是 nightly Rust,则可以切换到系统分配器。
另请参阅: