backtrace-rs icon indicating copy to clipboard operation
backtrace-rs copied to clipboard

still reachable bytes reported by valgrind.

Open nmahendru opened this issue 4 years ago • 3 comments

I am trying to use backtrace to get some error information in my application and unit tests report a lot of still reachable bytes when run under valgrind.

I am trying to use this on a hardware device with no probing capabilities so I am little specific of the memory usage and if something is off I try to avoid it. cargo version:

cargo 1.41.0 (626f0f40e 2019-12-03)

valgrind version:

valgrind --version
valgrind-3.14.0

Platform:

Linux 9eef3ca4a968 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 GNU/Linux

Simple example to reproduce:

use backtrace::Backtrace;

fn main() {
    println!("Hello, world!");
}

fn call_bt() {
    let bt = Backtrace::new();
    println!("{:?}", bt);
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_nothing() {
        call_bt();
    }
}

Cargo.toml


[dependencies]
backtrace = "0.3.50"

valgrind command:

valgrind --leak-check=full target/debug/deps/rust_try-116747691a975264

valgrind report:

==281== Memcheck, a memory error detector
==281== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==281== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==281== Command: target/debug/deps/rust_try-116747691a975264
==281==
==281== Syscall param statx(file_name) points to unaddressable byte(s)
==281==    at 0x493CF59: syscall (syscall.S:38)
==281==    by 0x2574BB: statx (weak.rs:90)
==281==    by 0x2574BB: std::sys::unix::fs::try_statx (fs.rs:132)
==281==    by 0x25238E: std::sys::unix::fs::stat (fs.rs:995)
==281==    by 0x159CB4: metadata<&std::path::PathBuf> (fs.rs:1591)
==281==    by 0x159CB4: term::terminfo::searcher::get_dbpath_for_term (searcher.rs:50)
==281==    by 0x158FB2: term::terminfo::TermInfo::from_name (mod.rs:87)
==281==    by 0x158DC0: term::terminfo::TermInfo::from_env (mod.rs:73)
==281==    by 0x163A09: new<std::io::stdio::Stdout> (mod.rs:232)
==281==    by 0x163A09: term::stdout (lib.rs:61)
==281==    by 0x1445CB: test::console::run_tests_console (console.rs:264)
==281==    by 0x14BFE3: test::test_main (lib.rs:121)
==281==    by 0x14CFF0: test::test_main_static (lib.rs:140)
==281==    by 0x12A695: rust_try::main (in /rust-try/target/debug/deps/rust_try-116747691a975264)
==281==    by 0x12A47F: std::rt::lang_start::{{closure}} (rt.rs:67)
==281==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==281==
==281== Syscall param statx(buf) points to unaddressable byte(s)
==281==    at 0x493CF59: syscall (syscall.S:38)
==281==    by 0x2574BB: statx (weak.rs:90)
==281==    by 0x2574BB: std::sys::unix::fs::try_statx (fs.rs:132)
==281==    by 0x25238E: std::sys::unix::fs::stat (fs.rs:995)
==281==    by 0x159CB4: metadata<&std::path::PathBuf> (fs.rs:1591)
==281==    by 0x159CB4: term::terminfo::searcher::get_dbpath_for_term (searcher.rs:50)
==281==    by 0x158FB2: term::terminfo::TermInfo::from_name (mod.rs:87)
==281==    by 0x158DC0: term::terminfo::TermInfo::from_env (mod.rs:73)
==281==    by 0x163A09: new<std::io::stdio::Stdout> (mod.rs:232)
==281==    by 0x163A09: term::stdout (lib.rs:61)
==281==    by 0x1445CB: test::console::run_tests_console (console.rs:264)
==281==    by 0x14BFE3: test::test_main (lib.rs:121)
==281==    by 0x14CFF0: test::test_main_static (lib.rs:140)
==281==    by 0x12A695: rust_try::main (in /rust-try/target/debug/deps/rust_try-116747691a975264)
==281==    by 0x12A47F: std::rt::lang_start::{{closure}} (rt.rs:67)
==281==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==281==

running 1 test
test tests::test_nothing ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

==281==
==281== HEAP SUMMARY:
==281==     in use at exit: 3,090,223 bytes in 4,093 blocks
==281==   total heap usage: 17,226 allocs, 13,133 frees, 8,883,150 bytes allocated
==281==
==281== LEAK SUMMARY:
==281==    definitely lost: 0 bytes in 0 blocks
==281==    indirectly lost: 0 bytes in 0 blocks
==281==      possibly lost: 0 bytes in 0 blocks
==281==    still reachable: 3,090,223 bytes in 4,093 blocks
==281==         suppressed: 0 bytes in 0 blocks
==281== Reachable blocks (those to which a pointer was found) are not shown.
==281== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==281==
==281== For counts of detected and suppressed errors, rerun with: -v
==281== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

nmahendru avatar Jul 24 '20 16:07 nmahendru

Yes gimli metadata is cached globally and currently not ever deallocated. AFAIK there's not really a way to deallocate this data globally, but other than valgrind it ideally shouldn't cause any issues.

alexcrichton avatar Jul 25 '20 04:07 alexcrichton

Thanks @alexcrichton for your response. I would like to ask that is there a ceiling to which this memory can grow ? I plan to do a Backtrace::new() on every error that I return from the embedded system and I can afford to allocate say 50 mb of memory. I am more worried if this allocation is gonna grow over time to sizes like 200 mb or more. Any comments on that ?

nmahendru avatar Jul 27 '20 18:07 nmahendru

There currently isn't a ceiling in terms of memory used, but the memory is indeed limited since what's persisted is an LRU global cache so eventually entries will be evicted before adding more.

alexcrichton avatar Jul 28 '20 14:07 alexcrichton

There doesn't seem to be anything we can realistically resolve here, so I am closing this. If you have a feature request for something that would make your life easier on this count, please open a new issue.

workingjubilee avatar Jun 22 '23 05:06 workingjubilee