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

It seems we got memory leaking? #108791

Closed
wisonye opened this issue Mar 5, 2023 · 7 comments
Closed

It seems we got memory leaking? #108791

wisonye opened this issue Mar 5, 2023 · 7 comments
Labels
C-bug Category: This is a bug.

Comments

@wisonye
Copy link

wisonye commented Mar 5, 2023

I tried this code:

fn main() {
    let what_you_want_to_say = "I'm Rust:)".to_string();
    println!("I'm so pound to say: {what_you_want_to_say}");
}

I expected to see this happen: Should no unfreed memory exists

Instead, this happeneed: But it seems memory is still reachable?

Meta

rustc --version --verbose:

rustc 1.66.0 (69f9c33d7 2022-12-12)
binary: rustc
commit-hash: 69f9c33d71c871fc16ac445211281c6e7a340943
commit-date: 2022-12-12
host: x86_64-unknown-freebsd
release: 1.66.0
LLVM version: 15.0.2
Backtrace

N  wison | /usr/home/wison/Rust/temp   valgrind --leak-check=full --show-reachable=yes -s ./target/release/temp
==9434== Memcheck, a memory error detector
==9434== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==9434== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==9434== Command: ./target/release/temp
==9434==
I'm so pound to say: I'm Rust:)
==9434==
==9434== HEAP SUMMARY:
==9434==     in use at exit: 1,853 bytes in 6 blocks
==9434==   total heap usage: 10 allocs, 4 frees, 2,983 bytes allocated
==9434==
==9434== 5 bytes in 1 blocks are still reachable in loss record 1 of 6
==9434==    at 0x484CBC4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x14C91F: alloc (alloc.rs:99)
==9434==    by 0x14C91F: alloc_impl (alloc.rs:181)
==9434==    by 0x14C91F: allocate (alloc.rs:241)
==9434==    by 0x14C91F: allocate_in<u8, alloc::alloc::Global> (raw_vec.rs:185)
==9434==    by 0x14C91F: with_capacity_in<u8, alloc::alloc::Global> (raw_vec.rs:131)
==9434==    by 0x14C91F: with_capacity_in<u8, alloc::alloc::Global> (mod.rs:673)
==9434==    by 0x14C91F: with_capacity<u8> (mod.rs:483)
==9434==    by 0x14C91F: spec_new_impl_bytes (c_str.rs:287)
==9434==    by 0x14C91F: <&str as alloc::ffi::c_str::CString::new::SpecNewImpl>::spec_new_impl (c_str.rs:306)
==9434==    by 0x12F11E: new<&str> (c_str.rs:316)
==9434==    by 0x12F11E: init (rt.rs:104)
==9434==    by 0x12F11E: {closure#1} (rt.rs:147)
==9434==    by 0x12F11E: do_call<std::rt::lang_start_internal::{closure_env#1}, ()> (panicking.rs:483)
==9434==    by 0x12F11E: try<(), std::rt::lang_start_internal::{closure_env#1}> (panicking.rs:447)
==9434==    by 0x12F11E: catch_unwind<std::rt::lang_start_internal::{closure_env#1}, ()> (panic.rs:137)
==9434==    by 0x12F11E: std::rt::lang_start_internal (rt.rs:147)
==9434==    by 0x11C044: main (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==
==9434== 16 bytes in 1 blocks are still reachable in loss record 2 of 6
==9434==    at 0x484CBC4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x137E72: alloc (alloc.rs:99)
==9434==    by 0x137E72: alloc_impl (alloc.rs:181)
==9434==    by 0x137E72: allocate (alloc.rs:241)
==9434==    by 0x137E72: exchange_malloc (alloc.rs:330)
==9434==    by 0x137E72: try_initialize<u8, std::sys_common::remutex::current_thread_unique_ptr::X::__getit::{closure_env#0}> (local.rs:1111)
==9434==    by 0x137E72: get<u8, std::sys_common::remutex::current_thread_unique_ptr::X::__getit::{closure_env#0}> (local.rs:1093)
==9434==    by 0x137E72: std::sys_common::remutex::current_thread_unique_ptr::X::__getit (local.rs:271)
==9434==    by 0x130B88: try_with<u8, std::sys_common::remutex::current_thread_unique_ptr::{closure_env#0}, usize> (local.rs:445)
==9434==    by 0x130B88: with<u8, std::sys_common::remutex::current_thread_unique_ptr::{closure_env#0}, usize> (local.rs:422)
==9434==    by 0x130B88: current_thread_unique_ptr (remutex.rs:177)
==9434==    by 0x130B88: lock<core::cell::RefCell<std::io::buffered::linewriter::LineWriter<std::io::stdio::StdoutRaw>>> (remutex.rs:97)
==9434==    by 0x130B88: lock (stdio.rs:657)
==9434==    by 0x130B88: <&std::io::stdio::Stdout as std::io::Write>::write_fmt (stdio.rs:716)
==9434==    by 0x1312D2: write_fmt (stdio.rs:690)
==9434==    by 0x1312D2: print_to<std::io::stdio::Stdout> (stdio.rs:1008)
==9434==    by 0x1312D2: std::io::stdio::_print (stdio.rs:1075)
==9434==    by 0x11BFC3: temp::main (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==    by 0x11C052: std::sys_common::backtrace::__rust_begin_short_backtrace (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==    by 0x11C068: std::rt::lang_start::{{closure}} (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==    by 0x12F1DE: call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (function.rs:286)
==9434==    by 0x12F1DE: do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panicking.rs:483)
==9434==    by 0x12F1DE: try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (panicking.rs:447)
==9434==    by 0x12F1DE: catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panic.rs:137)
==9434==    by 0x12F1DE: {closure#2} (rt.rs:148)
==9434==    by 0x12F1DE: do_call<std::rt::lang_start_internal::{closure_env#2}, isize> (panicking.rs:483)
==9434==    by 0x12F1DE: try<isize, std::rt::lang_start_internal::{closure_env#2}> (panicking.rs:447)
==9434==    by 0x12F1DE: catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> (panic.rs:137)
==9434==    by 0x12F1DE: std::rt::lang_start_internal (rt.rs:148)
==9434==    by 0x11C044: main (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==
==9434== 48 bytes in 1 blocks are still reachable in loss record 3 of 6
==9434==    at 0x484CBC4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x12F157: alloc (alloc.rs:99)
==9434==    by 0x12F157: alloc_impl (alloc.rs:181)
==9434==    by 0x12F157: allocate (alloc.rs:241)be
==9434==    by 0x12F157: {closure#0}<std::thread::Inner> (sync.rs:497)
==9434==    by 0x12F157: try_allocate_for_layout<core::mem::maybe_uninit::MaybeUninit<std::thread::Inner>, alloc::sync::{impl#13}::new_uninit::{closure_env#0}<std::thread::Inner>, alloc::sync::{impl#13}::new_uninit::{closure_env#1}<std::thread::Inner>> (sync.rs:1185)
==9434==    by 0x12F157: allocate_for_layout<core::mem::maybe_uninit::MaybeUninit<std::thread::Inner>, alloc::sync::{impl#13}::new_uninit::{closure_env#0}<std::thread::Inner>, alloc::sync::{impl#13}::new_uninit::{closure_env#1}<std::thread::Inner>> (sync.rs:1163)
==9434==    by 0x12F157: new_uninit<std::thread::Inner> (sync.rs:495)
==9434==    by 0x12F157: new (mod.rs:1216)
==9434==    by 0x12F157: init (rt.rs:104)
==9434==    by 0x12F157: {closure#1} (rt.rs:147)
==9434==    by 0x12F157: do_call<std::rt::lang_start_internal::{closure_env#1}, ()> (panicking.rs:483)
==9434==    by 0x12F157: try<(), std::rt::lang_start_internal::{closure_env#1}> (panicking.rs:447)
==9434==    by 0x12F157: catch_unwind<std::rt::lang_start_internal::{closure_env#1}, ()> (panic.rs:137)
==9434==    by 0x12F157: std::rt::lang_start_internal (rt.rs:147)
==9434==    by 0x11C044: main (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==
==9434== 56 bytes in 1 blocks are still reachable in loss record 4 of 6
==9434==    at 0x484CBC4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x137FA8: alloc (alloc.rs:99)
==9434==    by 0x137FA8: alloc_impl (alloc.rs:181)
==9434==    by 0x137FA8: allocate (alloc.rs:241)
==9434==    by 0x137FA8: exchange_malloc (alloc.rs:330)
==9434==    by 0x137FA8: try_initialize<core::cell::RefCell<core::option::Option<std::sys_common::thread_info::ThreadInfo>>, std::sys_common::thread_info::THREAD_INFO::__getit::{closure_env#0}> (local.rs:1111)
==9434==    by 0x137FA8: get<core::cell::RefCell<core::option::Option<std::sys_common::thread_info::ThreadInfo>>, std::sys_common::thread_info::THREAD_INFO::__getit::{closure_env#0}> (local.rs:1093)
==9434==    by 0x137FA8: std::sys_common::thread_info::THREAD_INFO::__getit (local.rs:271)
==9434==    by 0x1346BE: try_with<core::cell::RefCell<core::option::Option<std::sys_common::thread_info::ThreadInfo>>, std::sys_common::thread_info::set::{closure_env#0}, ()> (local.rs:445)
==9434==    by 0x1346BE: with<core::cell::RefCell<core::option::Option<std::sys_common::thread_info::ThreadInfo>>, std::sys_common::thread_info::set::{closure_env#0}, ()> (local.rs:422)
==9434==    by 0x1346BE: std::sys_common::thread_info::set (thread_info.rs:42)
==9434==    by 0x12F1CB: init (rt.rs:105)
==9434==    by 0x12F1CB: {closure#1} (rt.rs:147)
==9434==    by 0x12F1CB: do_call<std::rt::lang_start_internal::{closure_env#1}, ()> (panicking.rs:483)
==9434==    by 0x12F1CB: try<(), std::rt::lang_start_internal::{closure_env#1}> (panicking.rs:447)
==9434==    by 0x12F1CB: catch_unwind<std::rt::lang_start_internal::{closure_env#1}, ()> (panic.rs:137)
==9434==    by 0x12F1CB: std::rt::lang_start_internal (rt.rs:147)
==9434==    by 0x11C044: main (in /usr/home/wison/Rust/temp/target/release/temp)
==9434==
==9434== 64 bytes in 1 blocks are still reachable in loss record 5 of 6
==9434==    at 0x48500D5: calloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x4873C92: ??? (in /lib/libthr.so.3)
==9434==    by 0x486D229: ??? (in /lib/libthr.so.3)
==9434==    by 0x486C2DB: ??? (in /lib/libthr.so.3)
==9434==    by 0x400B0AC: ??? (in /libexec/ld-elf.so.1)
==9434==    by 0x40096AA: ??? (in /libexec/ld-elf.so.1)
==9434==    by 0x4007058: ??? (in /libexec/ld-elf.so.1)
==9434==
==9434== 1,664 bytes in 1 blocks are still reachable in loss record 6 of 6
==9434==    at 0x48500D5: calloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==9434==    by 0x486D218: ??? (in /lib/libthr.so.3)
==9434==    by 0x486C2DB: ??? (in /lib/libthr.so.3)
==9434==    by 0x400B0AC: ??? (in /libexec/ld-elf.so.1)
==9434==    by 0x40096AA: ??? (in /libexec/ld-elf.so.1)
==9434==    by 0x4007058: ??? (in /libexec/ld-elf.so.1)
==9434==
==9434== LEAK SUMMARY:
==9434==    definitely lost: 0 bytes in 0 blocks
==9434==    indirectly lost: 0 bytes in 0 blocks
==9434==      possibly lost: 0 bytes in 0 blocks
==9434==    still reachable: 1,853 bytes in 6 blocks
==9434==         suppressed: 0 bytes in 0 blocks
==9434==
==9434== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

@wisonye wisonye added the C-bug Category: This is a bug. label Mar 5, 2023
@clubby789
Copy link
Contributor

I'm guessing this is either a Valgrind bug or a FreeBSD-specific issue, I can't reproduce this

@workingjubilee
Copy link
Member

workingjubilee commented Mar 5, 2023

Which version of Valgrind are you both using? 3.20.0 and...?

It was for some time a known Valgrind issue that the tool would complain about memory that was deliberately left to be cleaned up by the process end. Perhaps they fixed it.

@workingjubilee
Copy link
Member

Oh, nevermind, 3.20 is the latest. I got nothin'.

It looks like the issue is mostly some thread-setup structures, including the stdio lock. That's all intentional.

@clubby789
Copy link
Contributor

Both 3.19 and 3.20 report no issues. #13420 made me wonder if this was something similar

@wisonye
Copy link
Author

wisonye commented Mar 6, 2023

Which version of Valgrind are you both using? 3.20.0 and...?

It was for some time a known Valgrind issue that the tool would complain about memory that was deliberately left to be cleaned up by the process end. Perhaps they fixed it.

Mine is valgrind-3.20.0

So, I think I leave this issue open, then other people will dive deep to have a look? :)

@workingjubilee
Copy link
Member

From the Valgrind FAQ, 5.2.:

With Memcheck's memory leak detector, what's the difference between "definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed"?

The details are in the Memcheck section of the user manual. In short:

  • "definitely lost" means your program is leaking memory -- fix those leaks!
  • "indirectly lost" means your program is leaking memory in a pointer-based structure. (E.g. if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the "definitely lost" leaks, the "indirectly lost" leaks should go away.
  • "possibly lost" means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block; see the user manual for some possible causes. Use --show-possibly-lost=no if you don't want to see these reports.
  • "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.
  • "suppressed" means that a leak error has been suppressed. There are some suppressions in the default suppression files. You can ignore suppressed errors.

So, per the Valgrind user manual, it's not an issue, and "definitely lost" and "still reachable" are not the same.

@Teapot4195
Copy link
Contributor

still reachable usually means that the program deliberately left some memory behind to be cleaned up by the os, os cleanup is actually faster than manually calling dealoc on all the memory, so it makes sense that rustc would leave the memory behind to be cleaned up by the os(the program is done anyways :)).

@nikic nikic closed this as not planned Won't fix, can't repro, duplicate, stale Mar 7, 2023
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

5 participants