Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Valgrind - memory still reachable when reading from stdin #124574

Closed
DorianCoding opened this issue May 1, 2024 · 2 comments
Closed

Valgrind - memory still reachable when reading from stdin #124574

DorianCoding opened this issue May 1, 2024 · 2 comments
Labels
C-bug Category: This is a bug.

Comments

@DorianCoding
Copy link

DorianCoding commented May 1, 2024

Hello, maybe I missed something but I tried this code:

use std::{io::{stdin, BufRead, Read}, process};
fn main() {
    //Let's read from stdin
    println!("Hello, what's your name?");
    let stdin = stdin().lock();
    let mut buffer = String::with_capacity(10);
    //Here we lock stdin and block to 10 bytes
    // Our string is now then only 10 bytes.
    //Even if it overflows like expected, it will reallocate.
    let mut stdin = stdin.take(40);
    if stdin.read_line(&mut buffer).is_err() {
        eprintln!("An error has occured while reading.");
        return;
    } //Now we print the result, our data is safe
    println!("Our string has a capacity of {}",buffer.capacity());
    println!("Hello {}!",buffer);
    //The string is freed automatically.
}
//Now let's try to overflow!! The string was reallocated.

I was expecting a casual memory free but Valgrind returns a memory leak :

==37491== 
==37491== HEAP SUMMARY:
==37491==     in use at exit: 8,192 bytes in 1 blocks
==37491==   total heap usage: 14 allocs, 13 frees, 11,423 bytes allocated
==37491== 
==37491== 8,192 bytes in 1 blocks are still reachable in loss record 1 of 1
==37491==    at 0x4840808: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==37491==    by 0x10F8A1: alloc (alloc.rs:98)
==37491==    by 0x10F8A1: alloc_impl (alloc.rs:181)
==37491==    by 0x10F8A1: allocate (alloc.rs:241)
==37491==    by 0x10F8A1: allocate_in<u8, alloc::alloc::Global> (raw_vec.rs:199)
==37491==    by 0x10F8A1: with_capacity_in<u8, alloc::alloc::Global> (raw_vec.rs:145)
==37491==    by 0x10F8A1: with_capacity<u8> (raw_vec.rs:107)
==37491==    by 0x10F8A1: new_uninit_slice<u8> (boxed.rs:635)
==37491==    by 0x10F8A1: with_capacity (buffer.rs:34)
==37491==    by 0x10F8A1: with_capacity<std::io::stdio::StdinRaw> (bufreader.rs:95)
==37491==    by 0x10F8A1: {closure#0} (stdio.rs:328)
==37491==    by 0x10F8A1: {closure#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}> (once_lock.rs:250)
==37491==    by 0x10F8A1: {closure#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}>, !> (once_lock.rs:376)
==37491==    by 0x10F8A1: {closure#0}<std::sync::once_lock::{impl#0}::initialize::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}>, !>> (once.rs:208)
==37491==    by 0x10F8A1: std::sys_common::once::futex::Once::call (futex.rs:124)
==37491==    by 0x10EEB9: call_once_force<std::sync::once_lock::{impl#0}::initialize::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}>, !>> (once.rs:208)
==37491==    by 0x10EEB9: std::sync::once_lock::OnceLock<T>::initialize (once_lock.rs:375)
==37491==    by 0x12D788: get_or_try_init<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}>, !> (once_lock.rs:298)
==37491==    by 0x12D788: get_or_init<std::sync::mutex::Mutex<std::io::buffered::bufreader::BufReader<std::io::stdio::StdinRaw>>, std::io::stdio::stdin::{closure_env#0}> (once_lock.rs:250)
==37491==    by 0x12D788: std::io::stdio::stdin (stdio.rs:327)
==37491==    by 0x113F20: test2::main (main.rs:5)
==37491==    by 0x1115FA: core::ops::function::FnOnce::call_once (function.rs:250)
==37491==    by 0x11247D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:155)
==37491==    by 0x111C00: std::rt::lang_start::{{closure}} (rt.rs:166)
==37491==    by 0x12BF80: call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (function.rs:284)
==37491==    by 0x12BF80: do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panicking.rs:554)
==37491==    by 0x12BF80: try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (panicking.rs:518)
==37491==    by 0x12BF80: catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panic.rs:142)
==37491==    by 0x12BF80: {closure#2} (rt.rs:148)
==37491==    by 0x12BF80: do_call<std::rt::lang_start_internal::{closure_env#2}, isize> (panicking.rs:554)
==37491==    by 0x12BF80: try<isize, std::rt::lang_start_internal::{closure_env#2}> (panicking.rs:518)
==37491==    by 0x12BF80: catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> (panic.rs:142)
==37491==    by 0x12BF80: std::rt::lang_start_internal (rt.rs:148)
==37491==    by 0x111BD9: std::rt::lang_start (rt.rs:165)
==37491==    by 0x11428D: main (in /home/guilhem/Bureau/test2/target/debug/test2)
==37491== 
==37491== LEAK SUMMARY:
==37491==    definitely lost: 0 bytes in 0 blocks
==37491==    indirectly lost: 0 bytes in 0 blocks
==37491==      possibly lost: 0 bytes in 0 blocks
==37491==    still reachable: 8,192 bytes in 1 blocks
==37491==         suppressed: 0 bytes in 0 blocks
==37491== 
==37491== For lists of detected and suppressed errors, rerun with: -s
==37491== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Meta

rustc --version --verbose:

rustc 1.77.2 (25ef9e3d8 2024-04-09)
rustc 1.80.0-nightly (a8a1d3a77 2024-04-29)
Backtrace

<backtrace>

Thank you.

@DorianCoding DorianCoding added the C-bug Category: This is a bug. label May 1, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 1, 2024
@DorianCoding DorianCoding changed the title Valgrind still reachable when reading from stdin Valgrind - memory still reachable when reading from stdin May 1, 2024
@workingjubilee
Copy link
Member

Please consult the Valgrind docs on what "still reachable" means:

"still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.

We allocate some things in global memory for various reasons, and it is a waste of our time to free these things when we could allow the OS to do so, as it can dispose of the global process state much faster than we or the allocator can. Unless you would rather we incur the overhead of allocating and deallocating that memory every time you issue a print?

Also see:

Closing.

@workingjubilee workingjubilee closed this as not planned Won't fix, can't repro, duplicate, stale May 3, 2024
@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants