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 shows memory leak for a simple print statement #19776

Closed
rjammala opened this issue Dec 12, 2014 · 36 comments
Closed

valgrind shows memory leak for a simple print statement #19776

rjammala opened this issue Dec 12, 2014 · 36 comments
Labels
A-codegen Area: Code generation A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@rjammala
Copy link

Here are the details:
$ valgrind --version
valgrind-3.8.1

rustc --version
rustc 0.13.0-nightly (193390d 2014-12-11 22:56:54 +0000)

uname -a
Linux 2.6.32-504.1.3.el6.x86_64 #1 SMP Tue Nov 11 17:57:25 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Here is the program:

$ cat learn.rs
fn main() {
println!("Hello World!")
println!("How are you today")
}

$ valgrind --leak-check=full ./learn
==38235== Memcheck, a memory error detector
==38235== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==38235== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==38235== Command: ./learn
==38235==

Hello World!
How are you today
==38235==
==38235== HEAP SUMMARY:
==38235== in use at exit: 1,184 bytes in 4 blocks
==38235== total heap usage: 18 allocs, 14 frees, 2,696 bytes allocated
==38235==
==38235== LEAK SUMMARY:
==38235== definitely lost: 0 bytes in 0 blocks
==38235== indirectly lost: 0 bytes in 0 blocks
==38235== possibly lost: 0 bytes in 0 blocks
==38235== still reachable: 1,184 bytes in 4 blocks
==38235== suppressed: 0 bytes in 0 blocks
==38235== Reachable blocks (those to which a pointer was found) are not shown.
==38235== To see them, rerun with: --leak-check=full --show-reachable=yes
==38235==
==38235== For counts of detected and suppressed errors, rerun with: -v
==38235== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

@alexcrichton
Copy link
Member

Can you run with --leak-check=full and --show-reachable=yes and paste the output here as well? I sadly can't reproduce this locally :(

@rjammala
Copy link
Author

$ valgrind --leak-check=full --show-reachable=yes ./learn
==3771== Memcheck, a memory error detector
==3771== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3771== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3771== Command: ./learn
==3771== 
Hello World!
How are you today
==3771== 
==3771== HEAP SUMMARY:
==3771==     in use at exit: 1,184 bytes in 4 blocks
==3771==   total heap usage: 18 allocs, 14 frees, 2,696 bytes allocated
==3771== 
==3771== 32 bytes in 1 blocks are still reachable in loss record 1 of 4
==3771==    at 0x128A12: je_mallocx (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11137F: thread_local::imp::register_dtor::h6d14515a39f84cf203b (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1129E3: thread_local::Key$LT$T$GT$::with::h7241079596358413660 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x112C42: io::stdio::with_task_stdout::hafb602ec3975fdc5syg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x115557: io::stdio::println_args::h7f0794513d4f2dfcxDg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1110B7: main::hbd01322dca53aee9eaa (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A22A: rt::start::closure.32122 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FEB: rust_try_inner (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FD5: rust_try (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123BB2: unwind::try::hf2f7fcf7ecc46c43Tyc (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123A8B: task::Task::run::h911f3b3bbb0c433efKb (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A05B: rt::start::hfd264fa826df3608S9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771== 
==3771== 64 bytes in 1 blocks are still reachable in loss record 2 of 4
==3771==    at 0x128A12: je_mallocx (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x111431: thread_local::imp::register_dtor::h6d14515a39f84cf203b (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1129E3: thread_local::Key$LT$T$GT$::with::h7241079596358413660 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x112C42: io::stdio::with_task_stdout::hafb602ec3975fdc5syg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x115557: io::stdio::println_args::h7f0794513d4f2dfcxDg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1110B7: main::hbd01322dca53aee9eaa (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A22A: rt::start::closure.32122 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FEB: rust_try_inner (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FD5: rust_try (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123BB2: unwind::try::hf2f7fcf7ecc46c43Tyc (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123A8B: task::Task::run::h911f3b3bbb0c433efKb (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A05B: rt::start::hfd264fa826df3608S9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771== 
==3771== 64 bytes in 1 blocks are still reachable in loss record 3 of 4
==3771==    at 0x128A12: je_mallocx (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x112CDD: io::stdio::with_task_stdout::hafb602ec3975fdc5syg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x115557: io::stdio::println_args::h7f0794513d4f2dfcxDg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1110B7: main::hbd01322dca53aee9eaa (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A22A: rt::start::closure.32122 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FEB: rust_try_inner (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FD5: rust_try (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123BB2: unwind::try::hf2f7fcf7ecc46c43Tyc (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123A8B: task::Task::run::h911f3b3bbb0c433efKb (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A05B: rt::start::hfd264fa826df3608S9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x119E35: rt::lang_start::hde2a214462357c7eb9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11117E: main (in /home/rjammalamadaka/Programs/Rust/learn)
==3771== 
==3771== 1,024 bytes in 1 blocks are still reachable in loss record 4 of 4
==3771==    at 0x128A12: je_mallocx (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x112222: io::buffered::BufferedWriter$LT$W$GT$::with_capacity::h8206835914802320726 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x112D63: io::stdio::with_task_stdout::hafb602ec3975fdc5syg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x115557: io::stdio::println_args::h7f0794513d4f2dfcxDg (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x1110B7: main::hbd01322dca53aee9eaa (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A22A: rt::start::closure.32122 (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FEB: rust_try_inner (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x124FD5: rust_try (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123BB2: unwind::try::hf2f7fcf7ecc46c43Tyc (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x123A8B: task::Task::run::h911f3b3bbb0c433efKb (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x11A05B: rt::start::hfd264fa826df3608S9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771==    by 0x119E35: rt::lang_start::hde2a214462357c7eb9x (in /home/rjammalamadaka/Programs/Rust/learn)
==3771== 
==3771== LEAK SUMMARY:
==3771==    definitely lost: 0 bytes in 0 blocks
==3771==    indirectly lost: 0 bytes in 0 blocks
==3771==      possibly lost: 0 bytes in 0 blocks
==3771==    still reachable: 1,184 bytes in 4 blocks
==3771==         suppressed: 0 bytes in 0 blocks
==3771== 
==3771== For counts of detected and suppressed errors, rerun with: -v
==3771== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

@alexcrichton
Copy link
Member

Interesting! It looks like destructors registered with pthread_key_create do not run when the process exits, causing this leak.

@rjammala
Copy link
Author

Let me know if you need any more information.

@huonw
Copy link
Member

huonw commented Jul 22, 2015

This seems to be resolved, at least the program with println!s has nothing still reachable.

@alexcrichton
Copy link
Member

@huonw did you test on linux? You may have been using the ELF TLS instead of pthread tls. I just built a compiler with --disable-elf-tls and it looks like the leak is still present:

$ valgrind ./foo 
==21255== Memcheck, a memory error detector
==21255== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21255== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==21255== Command: ./foo
==21255== 
Hello World!
How are you today
==21255== 
==21255== HEAP SUMMARY:
==21255==     in use at exit: 312 bytes in 7 blocks
==21255==   total heap usage: 26 allocs, 19 frees, 2,720 bytes allocated
==21255== 
==21255== LEAK SUMMARY:
==21255==    definitely lost: 0 bytes in 0 blocks
==21255==    indirectly lost: 0 bytes in 0 blocks
==21255==      possibly lost: 0 bytes in 0 blocks
==21255==    still reachable: 312 bytes in 7 blocks
==21255==         suppressed: 0 bytes in 0 blocks
==21255== Rerun with --leak-check=full to see details of leaked memory
==21255== 
==21255== For counts of detected and suppressed errors, rerun with: -v
==21255== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

@huonw
Copy link
Member

huonw commented Jul 22, 2015

Ah, yes, that looks like the difference.

@rjammala
Copy link
Author

It looks like this is no longer an issue (at least using nightly build of rust (1.7-0-nightly):

]$ valgrind ./learn
==79754== Memcheck, a memory error detector
==79754== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==79754== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==79754== Command: ./learn
==79754==
Hello World!
How are you today
==79754==
==79754== HEAP SUMMARY:
==79754== in use at exit: 0 bytes in 0 blocks
==79754== total heap usage: 4 allocs, 4 frees, 960 bytes allocated
==79754==
==79754== All heap blocks were freed -- no leaks are possible
==79754==
==79754== For counts of detected and suppressed errors, rerun with: -v
==79754== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
[rjammalamadaka@localhost Rust]$ rustc --version
rustc 1.7.0-nightly (81ae8be 2015-12-09)
[rjammalamadaka@localhost Rust]$

@tamird
Copy link
Contributor

tamird commented Dec 10, 2015

This is probably OK to close then

@alexcrichton
Copy link
Member

Ah unfortunately as I mentioned earlier this is specifically related to pthread TLS instead of ELF TLS (e.g. really old TLS). I just verified that this is indeed still an issue.

@steveklabnik
Copy link
Member

Trying this today:

$ ./configure --disable-elf-tls
$ make -j6
$ ./x86_64-unknown-linux-gnu/stage2/bin/rustc learn.rs 
$  valgrind --leak-check=full ./learn
==14462== Memcheck, a memory error detector
==14462== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14462== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==14462== Command: ./learn
==14462== 
Hello World!
How are you today
==14462== 
==14462== HEAP SUMMARY:
==14462==     in use at exit: 0 bytes in 0 blocks
==14462==   total heap usage: 22 allocs, 22 frees, 2,680 bytes allocated
==14462== 
==14462== All heap blocks were freed -- no leaks are possible
==14462== 
==14462== For counts of detected and suppressed errors, rerun with: -v
==14462== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ ./x86_64-unknown-linux-gnu/stage2/bin/rustc --version
rustc 1.10.0-dev (80bff1eea 2016-04-26)

Has this been randomly fixed?

@rjammala
Copy link
Author

yup, even I disabled elf-tls and it seems to have been fixed.
./configure --disable-elf-tls
$ ./x86_64-unknown-linux-gnu/stage2/bin/rustc --version
rustc 1.10.0-dev (80bff1e 2016-04-26)

@alexcrichton : Can we close this?

@tamird
Copy link
Contributor

tamird commented Apr 27, 2016

Probably needs a test to confirm it doesn't regress.

@alexcrichton
Copy link
Member

No, this is still an issue. The --disable-elf-tls option no longer works (that's a separate issue) and as I mentioned earlier (and earlier) this requires pthread TLS to be used, and by default we use ELF TLS so it's difficult to reproduce.

Running binaries on older systems with a working valgrind should reproduce this.

@steveklabnik
Copy link
Member

Gah! I didn't realize the flag didn't work; I thought I was using pthread TLS.

@tamird
Copy link
Contributor

tamird commented Apr 27, 2016

@alexcrichton can you cross-link to the --disable-elf-tls issue?

@alexcrichton
Copy link
Member

that'd be #32047

@jtsiros
Copy link

jtsiros commented Nov 8, 2016

Not sure if this is was resolved on nightly, but I see a similar issue for a trivial for a simple heap allocation testing using a bunch of Box::new() calls:

valgrind-3.12.0
rustc 1.12.1 (d4f3940 2016-10-19)
Darwin mC02QF11JG8WN 15.6.0 Darwin Kernel Version 15.6.0: Thu Sep 1 15:01:16 PDT 2016; root:xnu-3248.60.11~2/RELEASE_X86_64 x86_64

valgrind --leak-check=full --show-reachable=yes target/debug/sandbox
==55274== Memcheck, a memory error detector
==55274== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==55274== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==55274== Command: target/debug/sandbox
==55274==
==55274==
==55274== HEAP SUMMARY:
==55274==     in use at exit: 23,333 bytes in 187 blocks
==55274==   total heap usage: 275 allocs, 88 frees, 29,733 bytes allocated
==55274==
==55274== 112 bytes in 1 blocks are still reachable in loss record 39 of 64
==55274==    at 0x10005C681: malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==55274==    by 0x10019CD7C: tlv_allocate_and_initialize_for_key (in /usr/lib/system/libdyld.dylib)
==55274==    by 0x10019D52B: tlv_get_addr (in /usr/lib/system/libdyld.dylib)
==55274==    by 0x10000541D: std::sys_common::thread_info::set::h3ee71b197ed00dc8 (in target/debug/sandbox)
==55274==    by 0x100006782: std::rt::lang_start::hca48e539ce72a288 (in target/debug/sandbox)
==55274==    by 0x100001639: main (in target/debug/sandbox)
==55274==
==55274== 2,064 bytes in 1 blocks are possibly lost in loss record 61 of 64
==55274==    at 0x10005C942: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==55274==    by 0x10054EEFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x100542182: protocols() (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x100542093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x10053FC13: gc_init (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x10054724E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x100554132: layout_string_create (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x10054283C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x100542300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x1005422E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x1005422E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==55274==    by 0x1005422E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==55274==
==55274== LEAK SUMMARY:
==55274==    definitely lost: 0 bytes in 0 blocks
==55274==    indirectly lost: 0 bytes in 0 blocks
==55274==      possibly lost: 2,064 bytes in 1 blocks
==55274==    still reachable: 112 bytes in 1 blocks
==55274==         suppressed: 21,157 bytes in 185 blocks
==55274==
==55274== For counts of detected and suppressed errors, rerun with: -v
==55274== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 15)

@tbg
Copy link
Contributor

tbg commented Mar 13, 2017

still repros just like a charm, see below (seting of use-jemalloc doesn't matter, though of course the output varies somewhat). I'm happy to look more into why this is broken, but I'd need some guidance.

  1. apply this diff (adapt if you're not on x86_64_unknown_linux_gnu)
    index f95bcb5..dd93595 100644
    --- a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs
    +++ b/src/librustc_back/target/x86_64_unknown_linux_gnu.rs
    @@ -15,6 +15,7 @@ pub fn target() -> TargetResult {
         base.cpu = "x86-64".to_string();
         base.max_atomic_width = Some(64);
         base.pre_link_args.push("-m64".to_string());
    +    base.has_elf_tls = false;
    
         Ok(Target {
             llvm_target: "x86_64-unknown-linux-gnu".to_string(),
  2. ./x.py build src/libtest --stage 1 --incremental (or whichever you prefer)
  3. */*/stage1/*/rustc ~/learn.rs
  4. valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./learn
  5. find the leaks, plus Conditional jump or move depends on uninitialised value.
use-jemalloc=true (click to view)


valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./learn
==27188== Memcheck, a memory error detector
==27188== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==27188== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==27188== Command: ./learn
==27188==
==27188== Conditional jump or move depends on uninitialised value(s)
==27188==    at 0x119CB1: std::io::stdio::stdout::stdout_init::hde9bb20c74d239a0 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x117D3E: _$LT$std..io..lazy..Lazy$LT$T$GT$$GT$::get::hd42305ba5388eaca (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11A17E: std::io::stdio::_print::h909f88694efb8b49 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E6FF: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F292: std::panicking::try::do_call::h47aca5fe0bc0ca6f (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x124200: __rust_maybe_catch_panic (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F247: std::panicking::try::haf2827ba761d86f4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11B498: std::panic::catch_unwind::hd0e9dc562574f6f9 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F206: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==  Uninitialised value was created by a stack allocation
==27188==    at 0x119C52: std::io::stdio::stdout::stdout_init::hde9bb20c74d239a0 (in /home/tschottdorf/rust-pthread/learn)
==27188==
How are you today
==27188==
==27188== HEAP SUMMARY:
==27188==     in use at exit: 312 bytes in 7 blocks
==27188==   total heap usage: 22 allocs, 15 frees, 3,744 bytes allocated
==27188==
==27188== 8 bytes in 1 blocks are still reachable in loss record 1 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x123F30: _$LT$alloc..raw_vec..RawVec$LT$T$GT$$GT$::with_capacity::h9ac4354317bda4cc (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x124062: collections::slice::_$LT$impl$u20$collections..borrow..ToOwned$u20$for$u20$$u5b$T$u5d$$GT$::to_owned::ha76a6ec29817e7b5 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x123EE1: collections::str::_$LT$impl$u20$collections..borrow..ToOwned$u20$for$u20$str$GT$::to_owned::h471d5925d3705d5e (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F1D0: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 32 bytes in 1 blocks are still reachable in loss record 2 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x10E906: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::hf79eb5e1178b3ce0 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11141D: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::with::haff1cf65b443d42b (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F2B8: std::panicking::panicking::h4bf7d1f6b8817da7 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x1103BA: _$LT$std..sys_common..remutex..ReentrantMutex$LT$T$GT$$GT$::lock::h1f21b2cbcd0ed8ce (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x119E41: _$LT$std..io..stdio..Stdout$u20$as$u20$std..io..Write$GT$::write_fmt::hb0aeab83fe2aee50 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11A1D0: std::io::stdio::_print::h909f88694efb8b49 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E6FF: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F292: std::panicking::try::do_call::h47aca5fe0bc0ca6f (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x124200: __rust_maybe_catch_panic (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F247: std::panicking::try::haf2827ba761d86f4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11B498: std::panic::catch_unwind::hd0e9dc562574f6f9 (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 48 bytes in 1 blocks are still reachable in loss record 3 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x1165E0: _$LT$std..sync..mutex..Mutex$LT$T$GT$$GT$::new::hf4e3619dc58c81a2 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x110856: std::thread::Thread::new::ha2a11efc1d6ac4f2 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x110B5C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::h188fe40d655e3e09 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F1D8: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 48 bytes in 1 blocks are still reachable in loss record 4 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x1100F5: std::sync::condvar::Condvar::new::h4fbbad5b416fb56f (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x110860: std::thread::Thread::new::ha2a11efc1d6ac4f2 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x110B5C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::h188fe40d655e3e09 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F1D8: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 48 bytes in 1 blocks are still reachable in loss record 5 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x10E876: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::h307be15b67cc5cff (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x1117FB: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::with::hb38a09bf838c22e7 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11E5FD: std::sys_common::thread_info::set::h9bdea53d21fd0ea4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F1EF: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 48 bytes in 1 blocks are still reachable in loss record 6 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x10E7E6: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::h0a66dfc1cd407d9b (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x111902: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::state::h517ffedf5ce521c1 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11A156: std::io::stdio::_print::h909f88694efb8b49 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E6FF: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F292: std::panicking::try::do_call::h47aca5fe0bc0ca6f (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x124200: __rust_maybe_catch_panic (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11F247: std::panicking::try::haf2827ba761d86f4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x11B498: std::panic::catch_unwind::hd0e9dc562574f6f9 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F206: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== 80 bytes in 1 blocks are still reachable in loss record 7 of 7
==27188==    at 0x129DED: mallocx (jemalloc.c:2173)
==27188==    by 0x110896: std::thread::Thread::new::ha2a11efc1d6ac4f2 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x110B5C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::h188fe40d655e3e09 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10F1D8: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==27188==    by 0x10E739: main (in /home/tschottdorf/rust-pthread/learn)
==27188==
==27188== LEAK SUMMARY:
==27188==    definitely lost: 0 bytes in 0 blocks
==27188==    indirectly lost: 0 bytes in 0 blocks
==27188==      possibly lost: 0 bytes in 0 blocks
==27188==    still reachable: 312 bytes in 7 blocks
==27188==         suppressed: 0 bytes in 0 blocks
==27188==
==27188== For counts of detected and suppressed errors, rerun with: -v
==27188== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

use-jemalloc=false (click to view)


==18929== Memcheck, a memory error detector
==18929== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18929== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18929== Command: ./learn
==18929==
==18929== Conditional jump or move depends on uninitialised value(s)
==18929==    at 0x1174E1: std::io::stdio::stdout::stdout_init::h8c219ec6edaca9e2 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11556E: _$LT$std..io..lazy..Lazy$LT$T$GT$$GT$::get::h3818fe46065008a9 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x1179AE: std::io::stdio::_print::hb65c73db7e5ba8b4 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF2F: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CAC2: std::panicking::try::do_call::h4af13c61a0885795 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x121A30: __rust_maybe_catch_panic (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CA77: std::panicking::try::h5d0504a555a21656 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x118CC8: std::panic::catch_unwind::h8daeb6c836b441af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA36: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==  Uninitialised value was created by a stack allocation
==18929==    at 0x117482: std::io::stdio::stdout::stdout_init::h8c219ec6edaca9e2 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
How are you today
==18929==
==18929== HEAP SUMMARY:
==18929==     in use at exit: 277 bytes in 7 blocks
==18929==   total heap usage: 23 allocs, 16 frees, 3,560 bytes allocated
==18929==
==18929== 5 bytes in 1 blocks are still reachable in loss record 1 of 7
==18929==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10CB12: _$LT$alloc..raw_vec..RawVec$LT$T$GT$$GT$::reserve_exact::h4edf8f87d342a05f (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x118AE5: std::ffi::c_str::CString::from_vec_unchecked::hdcef4de01dead576 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x118A7D: std::ffi::c_str::CString::_new::hc7b7f6376e99eb50 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x1189B5: std::ffi::c_str::CString::new::h31a27631ea3d129f (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E01B: std::thread::Thread::new::hdbde4e93369830a6 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E38C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::hd92ec6def8113f36 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA08: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 24 bytes in 1 blocks are still reachable in loss record 2 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10C016: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::h4cb8adf76f34a8a8 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10EDAD: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::with::h7268ed135fa874a3 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CAE8: std::panicking::panicking::hf8bff814c3b72c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10DBEA: _$LT$std..sys_common..remutex..ReentrantMutex$LT$T$GT$$GT$::lock::hc072fd20cb222349 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x117671: _$LT$std..io..stdio..Stdout$u20$as$u20$std..io..Write$GT$::write_fmt::ha9551f3ca8d595e4 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x117A00: std::io::stdio::_print::hb65c73db7e5ba8b4 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF2F: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CAC2: std::panicking::try::do_call::h4af13c61a0885795 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x121A30: __rust_maybe_catch_panic (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CA77: std::panicking::try::h5d0504a555a21656 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x118CC8: std::panic::catch_unwind::h8daeb6c836b441af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 40 bytes in 1 blocks are still reachable in loss record 3 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x113E10: _$LT$std..sync..mutex..Mutex$LT$T$GT$$GT$::new::h2c7659a20efbd015 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E086: std::thread::Thread::new::hdbde4e93369830a6 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E38C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::hd92ec6def8113f36 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA08: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 40 bytes in 1 blocks are still reachable in loss record 4 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10C136: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::hf9087164760e6dbd (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10F132: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::state::h0545415cf9387211 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x117986: std::io::stdio::_print::hb65c73db7e5ba8b4 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF2F: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CAC2: std::panicking::try::do_call::h4af13c61a0885795 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x121A30: __rust_maybe_catch_panic (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11CA77: std::panicking::try::h5d0504a555a21656 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x118CC8: std::panic::catch_unwind::h8daeb6c836b441af (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA36: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 48 bytes in 1 blocks are still reachable in loss record 5 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10D925: std::sync::condvar::Condvar::new::h9b5a8a20b184aadc (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E090: std::thread::Thread::new::hdbde4e93369830a6 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E38C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::hd92ec6def8113f36 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA08: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 48 bytes in 1 blocks are still reachable in loss record 6 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10C0A6: _$LT$std..thread..local..os..Key$LT$T$GT$$GT$::get::hbf071f63bdfa8db8 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10EE1B: _$LT$std..thread..local..LocalKey$LT$T$GT$$GT$::with::ha1974f44b6021a71 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x11BE2D: std::sys_common::thread_info::set::hcd1ca419433f28db (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA1F: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== 72 bytes in 1 blocks are still reachable in loss record 7 of 7
==18929==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18929==    by 0x10E0C6: std::thread::Thread::new::hdbde4e93369830a6 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10E38C: _$LT$std..thread..Thread$u20$as$u20$std..sys_common..thread_info..NewThread$GT$::new::hd92ec6def8113f36 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10CA08: std::rt::lang_start::h74f5ad66fb152c57 (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==    by 0x10BF69: main (in /home/tschottdorf/rust-nojemalloc/learn)
==18929==
==18929== LEAK SUMMARY:
==18929==    definitely lost: 0 bytes in 0 blocks
==18929==    indirectly lost: 0 bytes in 0 blocks
==18929==      possibly lost: 0 bytes in 0 blocks
==18929==    still reachable: 277 bytes in 7 blocks
==18929==         suppressed: 0 bytes in 0 blocks
==18929==
==18929== For counts of detected and suppressed errors, rerun with: -v
==18929== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

@tbg
Copy link
Contributor

tbg commented Mar 13, 2017

Oh, btw, the Conditional jump or move depends on uninitialised value(s) is always there (i.e. even when you don't apply the patch). So that's probably new. Isn't this run in CI somewhere?

==31040== Memcheck, a memory error detector
==31040== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==31040== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==31040== Command: ./learn
==31040==
==31040== Conditional jump or move depends on uninitialised value(s)
==31040==    at 0x10EB61: std::io::stdio::stdout::stdout_init::hde9bb20c74d239a0 (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x11DC3E: _$LT$std..io..lazy..Lazy$LT$T$GT$$GT$::get::hd42305ba5388eaca (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x10F02E: std::io::stdio::_print::h909f88694efb8b49 (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x10E6EF: learn::main::h86b1088ba10af1af (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x113922: std::panicking::try::do_call::h47aca5fe0bc0ca6f (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x124260: __rust_maybe_catch_panic (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x1138D7: std::panicking::try::haf2827ba761d86f4 (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x110956: std::rt::lang_start::h8c02412f0e1905c4 (in /home/tschottdorf/rust-pthread/learn)
==31040==    by 0x10E729: main (in /home/tschottdorf/rust-pthread/learn)
==31040==  Uninitialised value was created by a stack allocation
==31040==    at 0x10EB02: std::io::stdio::stdout::stdout_init::hde9bb20c74d239a0 (in /home/tschottdorf/rust-pthread/learn)
==31040==
How are you today
==31040==
==31040== HEAP SUMMARY:
==31040==     in use at exit: 0 bytes in 0 blocks
==31040==   total heap usage: 21 allocs, 21 frees, 3,680 bytes allocated
==31040==
==31040== All heap blocks were freed -- no leaks are possible
==31040==
==31040== For counts of detected and suppressed errors, rerun with: -v
==31040== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

@arielb1
Copy link
Contributor

arielb1 commented Mar 13, 2017

Oh, btw, the Conditional jump or move depends on uninitialised value(s) is always there (i.e. even when you don't apply the patch).

That warning is harmless, and caused by LLVM optimization - see https://bugs.llvm.org//show_bug.cgi?id=23180 .

@o01eg
Copy link
Contributor

o01eg commented Mar 13, 2017

Can compiler just optimize out condition?

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@steveklabnik
Copy link
Member

Triage: I do not have the means to attempt to reproduce today, but we did recently switch to the system allocator; I wonder if the bug persists. Anyone?

@devMYC
Copy link

devMYC commented Dec 13, 2018

$ rustc --version
rustc 1.31.0 (abe02cefd 2018-12-04)
$
$
$ cat raii.rs 
fn create_box() {
  let _box = Box::new(1u8);
}

fn main() {
  let _box_one = Box::new(10u8);

  {
    let _box_two = Box::new(20u8);
  }

  for _ in 0u16..1_000 {
    create_box();
  }
}
$
$
$ rustc raii.rs && valgrind --leak-check=full --show-leak-kinds=all ./raii
==43885== Memcheck, a memory error detector
==43885== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43885== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==43885== Command: ./raii
==43885== 
--43885-- run: /usr/bin/dsymutil "./raii"
==43885== 
==43885== HEAP SUMMARY:
==43885==     in use at exit: 18,719 bytes in 162 blocks
==43885==   total heap usage: 184 allocs, 22 frees, 27,191 bytes allocated
==43885== 
==43885== 24 bytes in 1 blocks are still reachable in loss record 3 of 44
==43885==    at 0x1001332FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x100807901: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885==    by 0x100805073: _objc_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10025AB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==43885== 
==43885== 32 bytes in 1 blocks are still reachable in loss record 8 of 44
==43885==    at 0x1001332FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x100807A9E: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807A6E: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807948: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885== 
==43885== 32 bytes in 1 blocks are still reachable in loss record 9 of 44
==43885==    at 0x1001332FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x100807ABF: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807A6E: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807948: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885== 
==43885== 32 bytes in 1 blocks are still reachable in loss record 10 of 44
==43885==    at 0x100133086: malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x100807B83: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807A6E: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807948: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885== 
==43885== 32 bytes in 1 blocks are still reachable in loss record 11 of 44
==43885==    at 0x100133086: malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x1008079AE: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885==    by 0x100805073: _objc_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10025AB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==43885== 
==43885== 48 bytes in 1 blocks are still reachable in loss record 15 of 44
==43885==    at 0x1001338AD: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x100807F24: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807EA2: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807BAD: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807A6E: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100807948: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008078D3: NXCreateMapTable (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806394: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x100806096: sel_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10080598C: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885== 
==43885== 72 bytes in 3 blocks are possibly lost in loss record 26 of 44
==43885==    at 0x1001336EA: calloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x1008057C2: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x1008184E0: map_images (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10008EC64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==43885==    by 0x10008EE39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==43885==    by 0x1002D071D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==43885==    by 0x100805073: _objc_init (in /usr/lib/libobjc.A.dylib)
==43885==    by 0x10025AB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==43885==    by 0x10025AB1B: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==43885==    by 0x1001419C2: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==43885==    by 0x1000A0AC5: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==43885==    by 0x1000A0CF5: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==43885== 
==43885== 112 bytes in 1 blocks are still reachable in loss record 27 of 44
==43885==    at 0x100133086: malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==43885==    by 0x1002D0969: tlv_allocate_and_initialize_for_key (in /usr/lib/system/libdyld.dylib)
==43885==    by 0x1002D10EB: tlv_get_addr (in /usr/lib/system/libdyld.dylib)
==43885==    by 0x10000938E: std::sys_common::thread_info::THREAD_INFO::__getit (cell.rs:258)
==43885==    by 0x10000A21F: <std::thread::local::LocalKey<T>>::with (local.rs:297)
==43885==    by 0x100008599: std::rt::lang_start_internal (thread_info.rs:47)
==43885==    by 0x1000017A1: std::rt::lang_start (in ./raii)
==43885==    by 0x100001371: main (in ./raii)
==43885== 
==43885== LEAK SUMMARY:
==43885==    definitely lost: 0 bytes in 0 blocks
==43885==    indirectly lost: 0 bytes in 0 blocks
==43885==      possibly lost: 72 bytes in 3 blocks
==43885==    still reachable: 312 bytes in 7 blocks
==43885==         suppressed: 18,335 bytes in 152 blocks
==43885== 
==43885== For counts of detected and suppressed errors, rerun with: -v
==43885== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 9 from 9)

@tesuji
Copy link
Contributor

tesuji commented Jan 17, 2019

Edit: Resolved with latest valgrind (3.15.0)

Resolved
```r2
$ uname -a
Linux up 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
```

---

@devMYC Same program as your (named `tmp.rs`)

```rust
fn create_box() {
    let _box = Box::new(1u8);
}
fn main() {
    let _box_one = Box::new(10u8);
    {
        let _box_two = Box::new(20u8);
    }
    for _ in 0u16..1_000 {
        create_box();
    }
}
```

My result is different:

```r2
$ rustc +nightly -V
rustc 1.33.0-nightly (ceb251214 2019-01-16)
$ rustc -V
rustc 1.31.1 (b6c32da9b 2018-12-18)
$ rustc +nightly tmp.rs -o tmp_nightly
$ rustc          tmp.rs -o tmp_stable
$ valgrind --version
valgrind-3.13.0
$ valgrind ./tmp_stable
[...]
==9461== HEAP SUMMARY:
==9461==     in use at exit: 0 bytes in 0 blocks
==9461==   total heap usage: 6 allocs, 6 frees, 2,000 bytes allocated
==9461==
==9461== All heap blocks were freed -- no leaks are possible
[...]
$ valgrind ./tmp_nightly
[...]
==9463== HEAP SUMMARY:
==9463==     in use at exit: 0 bytes in 0 blocks
==9463==   total heap usage: 1,013 allocs, 1,013 frees, 3,179 bytes allocated
==9463==
==9463== All heap blocks were freed -- no leaks are possible
[...]
```

But the follow code has leak:

```rust
use std::thread;
const NTHREADS: i32 = 10;
// This is the `main` thread
fn main() {
    // Make a vector to hold the children which are spawned.
    let mut children = vec![];
    for i in 0..NTHREADS {
        // Spin up another thread
        children.push(thread::spawn(move || {
            i + NTHREADS + 2
        }));
    }
    for child in children {
        // Wait for the thread to finish. Returns a result.
        let _ = child.join();
    }
}
```

```r2
$ valgrind ./tmp_nightly
[..]
==9866== HEAP SUMMARY:
==9866==     in use at exit: 32 bytes in 1 blocks
==9866==   total heap usage: 111 allocs, 110 frees, 9,275 bytes allocated
==9866== 
==9866== LEAK SUMMARY:
==9866==    definitely lost: 0 bytes in 0 blocks
==9866==    indirectly lost: 0 bytes in 0 blocks
==9866==      possibly lost: 0 bytes in 0 blocks
==9866==    still reachable: 32 bytes in 1 blocks
==9866==         suppressed: 0 bytes in 0 blocks
==9866== Rerun with --leak-check=full to see details of leaked memory
[..]
$ valgrind ./tmp_stable 
[..]
==9879== HEAP SUMMARY:
==9879==     in use at exit: 32 bytes in 1 blocks
==9879==   total heap usage: 37 allocs, 36 frees, 5,552 bytes allocated
==9879== 
==9879== LEAK SUMMARY:
==9879==    definitely lost: 0 bytes in 0 blocks
==9879==    indirectly lost: 0 bytes in 0 blocks
==9879==      possibly lost: 0 bytes in 0 blocks
==9879==    still reachable: 32 bytes in 1 blocks
==9879==         suppressed: 0 bytes in 0 blocks
==9879== Rerun with --leak-check=full to see details of leaked memory
[..]
```

@mal20k
Copy link

mal20k commented Aug 21, 2019

I'm running into what looks to be a related issue when trying to call a Rust function from C. According to valgrind, memory is leaked when Rust allocates the handle for stdout or stderr, but only once. Subsequent calls to println!, eprintln! std::io::stdout(), even across function calls, don't add to the count (always 8 allocs, 1 free). Could this be related or it it caused by some other issue?

$ uname -a
Linux Bastion 4.10.17-2-pve #1 SMP PVE 4.10.17-20 (Mon, 14 Aug 2017 11:23:37 +0200) x86_64 GNU/Linux
$ rustc --version
rustc 1.37.0 (eae3437df 2019-08-13)
$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
// main.c
void print_things();
void main() {
    print_things();
}
// lib.rs
#[no_mangle]
pub extern "C" fn print_things() {
    println!("Hello, world!");
}
$ LD_LIBRARY_PATH=../target/debug/ valgrind --leak-check=full --show-leak-kinds=all --trace-children=yes ./test.out
==9724== Memcheck, a memory error detector
==9724== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9724== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==9724== Command: ./test.out
==9724== 
==9724== 
==9724== HEAP SUMMARY:
==9724==     in use at exit: 1,200 bytes in 7 blocks
==9724==   total heap usage: 8 allocs, 1 frees, 1,232 bytes allocated
==9724== 
==9724== 8 bytes in 1 blocks are still reachable in loss record 1 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484A7F8: alloc (alloc.rs:81)
==9724==    by 0x484A7F8: exchange_malloc (alloc.rs:203)
==9724==    by 0x484A7F8: new<closure> (boxed.rs:113)
==9724==    by 0x484A7F8: at_exit<closure> (mod.rs:123)
==9724==    by 0x484A7F8: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:48)
==9724==    by 0x484A7F8: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A7F8: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 8 bytes in 1 blocks are still reachable in loss record 2 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484A973: alloc (alloc.rs:81)
==9724==    by 0x484A973: exchange_malloc (alloc.rs:203)
==9724==    by 0x484A973: new<alloc::sync::Arc<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>>> (boxed.rs:113)
==9724==    by 0x484A973: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:60)
==9724==    by 0x484A973: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A973: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 16 bytes in 1 blocks are still reachable in loss record 3 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484CA25: alloc (alloc.rs:81)
==9724==    by 0x484CA25: alloc (alloc.rs:169)
==9724==    by 0x484CA25: reserve_internal<alloc::boxed::Box<FnOnce<()>>,alloc::alloc::Global> (raw_vec.rs:668)
==9724==    by 0x484CA25: reserve<alloc::boxed::Box<FnOnce<()>>,alloc::alloc::Global> (raw_vec.rs:491)
==9724==    by 0x484CA25: reserve<alloc::boxed::Box<FnOnce<()>>> (vec.rs:457)
==9724==    by 0x484CA25: push<alloc::boxed::Box<FnOnce<()>>> (vec.rs:1033)
==9724==    by 0x484CA25: std::sys_common::at_exit_imp::push (at_exit_imp.rs:69)
==9724==    by 0x484A813: at_exit<closure> (mod.rs:123)
==9724==    by 0x484A813: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:48)
==9724==    by 0x484A813: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A813: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 24 bytes in 1 blocks are still reachable in loss record 4 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484C94A: alloc (alloc.rs:81)
==9724==    by 0x484C94A: exchange_malloc (alloc.rs:203)
==9724==    by 0x484C94A: init (at_exit_imp.rs:30)
==9724==    by 0x484C94A: std::sys_common::at_exit_imp::push (at_exit_imp.rs:66)
==9724==    by 0x484A813: at_exit<closure> (mod.rs:123)
==9724==    by 0x484A813: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:48)
==9724==    by 0x484A813: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A813: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 40 bytes in 1 blocks are still reachable in loss record 5 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484A862: alloc (alloc.rs:81)
==9724==    by 0x484A862: exchange_malloc (alloc.rs:203)
==9724==    by 0x484A862: new<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>> (remutex.rs:54)
==9724==    by 0x484A862: stdout_init (stdio.rs:480)
==9724==    by 0x484A862: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:58)
==9724==    by 0x484A862: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A862: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 80 bytes in 1 blocks are still reachable in loss record 6 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484A8DE: alloc (alloc.rs:81)
==9724==    by 0x484A8DE: exchange_malloc (alloc.rs:203)
==9724==    by 0x484A8DE: new<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (sync.rs:288)
==9724==    by 0x484A8DE: stdout_init (stdio.rs:480)
==9724==    by 0x484A8DE: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:58)
==9724==    by 0x484A8DE: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A8DE: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== 1,024 bytes in 1 blocks are still reachable in loss record 7 of 7
==9724==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==9724==    by 0x484A826: alloc (alloc.rs:81)
==9724==    by 0x484A826: alloc (alloc.rs:169)
==9724==    by 0x484A826: allocate_in<u8,alloc::alloc::Global> (raw_vec.rs:95)
==9724==    by 0x484A826: with_capacity<u8> (raw_vec.rs:139)
==9724==    by 0x484A826: with_capacity<u8> (vec.rs:355)
==9724==    by 0x484A826: with_capacity<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>> (buffered.rs:484)
==9724==    by 0x484A826: with_capacity<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>> (buffered.rs:857)
==9724==    by 0x484A826: new<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>> (buffered.rs:836)
==9724==    by 0x484A826: stdout_init (stdio.rs:480)
==9724==    by 0x484A826: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:58)
==9724==    by 0x484A826: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::buffered::LineWriter<std::io::stdio::Maybe<std::io::stdio::StdoutRaw>>>>> (lazy.rs:34)
==9724==    by 0x484A826: std::io::stdio::stdout (stdio.rs:470)
==9724==    by 0x484AF17: {{closure}}<std::io::stdio::Stdout> (stdio.rs:786)
==9724==    by 0x484AF17: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:299)
==9724==    by 0x484AF17: print_to<std::io::stdio::Stdout> (stdio.rs:780)
==9724==    by 0x484AF17: std::io::stdio::_print (stdio.rs:802)
==9724==    by 0x48475A3: print_things (lib.rs:3)
==9724==    by 0x1086CD: main (in /home/proxmox/Projects/test-things/src/test.out)
==9724== 
==9724== LEAK SUMMARY:
==9724==    definitely lost: 0 bytes in 0 blocks
==9724==    indirectly lost: 0 bytes in 0 blocks
==9724==      possibly lost: 0 bytes in 0 blocks
==9724==    still reachable: 1,200 bytes in 7 blocks
==9724==         suppressed: 0 bytes in 0 blocks
==9724== 
==9724== For counts of detected and suppressed errors, rerun with: -v
==9724== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

@sebpuetz
Copy link

I'm encountering the same behaviour with Rust -> C -> C++

$ uname -a
Linux seb-desktop 5.0.0-25-generic #26~18.04.1-Ubuntu SMP Thu Aug 1 13:51:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
$ rustc --version
rustc 1.37.0 (eae3437df 2019-08-13)
#[no_mangle]
pub extern "C" fn print_something() {
eprintln!("something");
}
int main() {
  print_something();
  return 0;
}
RUSTFLAGS="-g -C opt-level=0" cargo build
g++ main.cpp -L ./target/debug/ -lfinalfusion_tf -o run -g -O0
valgrind --leak-check=full --show-leak-kinds=all  --trace-children=yes ./run
==975== Memcheck, a memory error detector
==975== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==975== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==975== Command: ./run
==975== 
something
==975== 
==975== HEAP SUMMARY:
==975==     in use at exit: 144 bytes in 6 blocks
==975==   total heap usage: 7 allocs, 1 frees, 176 bytes allocated
==975== 
==975== 8 bytes in 1 blocks are still reachable in loss record 1 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB0196: alloc (alloc.rs:82)
==975==    by 0x4EB0196: exchange_malloc (alloc.rs:204)
==975==    by 0x4EB0196: new<closure> (boxed.rs:116)
==975==    by 0x4EB0196: at_exit<closure> (mod.rs:117)
==975==    by 0x4EB0196: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:48)
==975==    by 0x4EB0196: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB0196: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== 8 bytes in 1 blocks are still reachable in loss record 2 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB02AD: alloc (alloc.rs:82)
==975==    by 0x4EB02AD: exchange_malloc (alloc.rs:204)
==975==    by 0x4EB02AD: new<alloc::sync::Arc<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>>> (boxed.rs:116)
==975==    by 0x4EB02AD: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:60)
==975==    by 0x4EB02AD: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB02AD: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== 16 bytes in 1 blocks are still reachable in loss record 3 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB2105: alloc (alloc.rs:82)
==975==    by 0x4EB2105: alloc (alloc.rs:170)
==975==    by 0x4EB2105: reserve_internal<alloc::boxed::Box<FnOnce<()>>,alloc::alloc::Global> (raw_vec.rs:668)
==975==    by 0x4EB2105: reserve<alloc::boxed::Box<FnOnce<()>>,alloc::alloc::Global> (raw_vec.rs:491)
==975==    by 0x4EB2105: reserve<alloc::boxed::Box<FnOnce<()>>> (vec.rs:457)
==975==    by 0x4EB2105: push<alloc::boxed::Box<FnOnce<()>>> (vec.rs:1102)
==975==    by 0x4EB2105: std::sys_common::at_exit_imp::push (at_exit_imp.rs:69)
==975==    by 0x4EB01B1: at_exit<closure> (mod.rs:117)
==975==    by 0x4EB01B1: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:48)
==975==    by 0x4EB01B1: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB01B1: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== 24 bytes in 1 blocks are still reachable in loss record 4 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB202A: alloc (alloc.rs:82)
==975==    by 0x4EB202A: exchange_malloc (alloc.rs:204)
==975==    by 0x4EB202A: init (at_exit_imp.rs:30)
==975==    by 0x4EB202A: std::sys_common::at_exit_imp::push (at_exit_imp.rs:66)
==975==    by 0x4EB01B1: at_exit<closure> (mod.rs:117)
==975==    by 0x4EB01B1: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:48)
==975==    by 0x4EB01B1: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB01B1: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== 40 bytes in 1 blocks are still reachable in loss record 5 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB01C4: alloc (alloc.rs:82)
==975==    by 0x4EB01C4: exchange_malloc (alloc.rs:204)
==975==    by 0x4EB01C4: new<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>> (remutex.rs:54)
==975==    by 0x4EB01C4: stderr_init (stdio.rs:639)
==975==    by 0x4EB01C4: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:58)
==975==    by 0x4EB01C4: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB01C4: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== 48 bytes in 1 blocks are still reachable in loss record 6 of 6
==975==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==975==    by 0x4EB0243: alloc (alloc.rs:82)
==975==    by 0x4EB0243: exchange_malloc (alloc.rs:204)
==975==    by 0x4EB0243: new<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (sync.rs:288)
==975==    by 0x4EB0243: stderr_init (stdio.rs:639)
==975==    by 0x4EB0243: init<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:58)
==975==    by 0x4EB0243: get<std::sys_common::remutex::ReentrantMutex<core::cell::RefCell<std::io::stdio::Maybe<std::io::stdio::StderrRaw>>>> (lazy.rs:34)
==975==    by 0x4EB0243: std::io::stdio::stderr (stdio.rs:629)
==975==    by 0x4EB0772: {{closure}}<std::io::stdio::Stderr> (stdio.rs:786)
==975==    by 0x4EB0772: try_with<core::cell::RefCell<core::option::Option<alloc::boxed::Box<Write>>>,closure,core::result::Result<(), std::io::error::Error>> (local.rs:257)
==975==    by 0x4EB0772: print_to<std::io::stdio::Stderr> (stdio.rs:780)
==975==    by 0x4EB0772: std::io::stdio::_eprint (stdio.rs:811)
==975==    by 0x4E4A1B3: print_something (embeddings_wrap.rs:147)
==975==    by 0x108662: main (main.cpp:13)
==975== 
==975== LEAK SUMMARY:
==975==    definitely lost: 0 bytes in 0 blocks
==975==    indirectly lost: 0 bytes in 0 blocks
==975==      possibly lost: 0 bytes in 0 blocks
==975==    still reachable: 144 bytes in 6 blocks
==975==         suppressed: 0 bytes in 0 blocks
==975== 
==975== For counts of detected and suppressed errors, rerun with: -v
==975== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

@mal20k
Copy link

mal20k commented Mar 7, 2020

Still seeing this in 1.41.1, same test program as my previous comment.

What would be needed to resolve this issue? Is there a workaround that can be done or just avoid using stdout/stderr in Rust code called from C?

$ LD_LIBRARY_PATH=./target/debug/ valgrind ./call_rust
==13954== Memcheck, a memory error detector
==13954== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13954== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==13954== Command: ./call_rust
==13954==
Hello, world!
==13954==
==13954== HEAP SUMMARY:
==13954==     in use at exit: 1,200 bytes in 7 blocks
==13954==   total heap usage: 8 allocs, 1 frees, 1,232 bytes allocated
==13954==
==13954== LEAK SUMMARY:
==13954==    definitely lost: 0 bytes in 0 blocks
==13954==    indirectly lost: 0 bytes in 0 blocks
==13954==      possibly lost: 0 bytes in 0 blocks
==13954==    still reachable: 1,200 bytes in 7 blocks
==13954==         suppressed: 0 bytes in 0 blocks
==13954== Rerun with --leak-check=full to see details of leaked memory
==13954==
==13954== For counts of detected and suppressed errors, rerun with: -v
==13954== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

@sfackler
Copy link
Member

sfackler commented Mar 7, 2020

Is there a workaround that can be done or just avoid using stdout/stderr in Rust code called from C?

How do those 7 allocations negatively impact your program?

@mal20k
Copy link

mal20k commented Mar 8, 2020

How do those 7 allocations negatively impact your program?

Mostly personal curiosity since I don't know a whole lot about what's causing this. But also my company has been considering allowing us to use Rust with our existing C codebase and management tends to focus pretty hard on any kind of memory leak occurring.

@taro-yamada
Copy link

It seems that when we call println first time, it register a closure to drop the resource at the end of the program.

// If we successfully register an at exit handler, then we cache the
// `Arc` allocation in our own internal box (it will get deallocated by
// the at exit handler). Otherwise we just return the freshly allocated
// `Arc`.
let registered = sys_common::at_exit(move || {
let ptr = {
let _guard = self.lock.lock();
self.ptr.replace(done())
};
drop(Box::from_raw(ptr))
});

If we call println from normal Rust program, lang_start_internal execute that closure at the end and memory freed.

sys_common::cleanup();

at_exit_imp::cleanup();

pub fn cleanup() {

But if we call it from C program, lang_start_internal will not be executed and registered closures will not be executed too and the resource will be leaked.

@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) labels Apr 20, 2020
@inancgumus
Copy link

inancgumus commented May 31, 2020

It looks like, this problem is still alive.

~/leak ❯ valgrind --version
valgrind-3.16.0.GIT
~/leak ❯ rustc --version
rustc 1.33.0
~/leak ❯ uname -a
Darwin x.local 19.5.0 Darwin Kernel Version 19.5.0: Thu Apr 30 18:25:59 PDT 2020; root:xnu-6153.121.1~7/RELEASE_X86_64 x86_64
~/leak ❯ cat src/main.rs
fn main() {
    println!("Hello World!");
    println!("How are you today");
}
~/leak ❯ rustc src/main.rs && valgrind --leak-check=full --show-reachable=yes ./main
==2304== Memcheck, a memory error detector
==2304== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2304== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==2304== Command: ./main
==2304== 
Hello World!
How are you today
==2304== 
==2304== HEAP SUMMARY:
==2304==     in use at exit: 14,803 bytes in 163 blocks
==2304==   total heap usage: 191 allocs, 28 frees, 21,036 bytes allocated
==2304== 
==2304== 14 bytes in 1 blocks are still reachable in loss record 1 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1004362AA: __setenv_locked (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x1004366A3: setenv (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x1006D83E6: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304==    by 0x10004D59F: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==2304== 
==2304== 16 bytes in 1 blocks are indirectly lost in loss record 2 of 38
==2304==    at 0x100157E51: malloc_zone_calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E29D: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073DFFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 32 bytes in 1 blocks are indirectly lost in loss record 3 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E21B: _NXMapMember(_NXMapTable*, void const*, void**) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073DFFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 32 bytes in 1 blocks are indirectly lost in loss record 4 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E04F: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 32 bytes in 1 blocks are definitely lost in loss record 5 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304== 
==2304== 32 bytes in 1 blocks are definitely lost in loss record 6 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304== 
==2304== 32 bytes in 1 blocks are definitely lost in loss record 7 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1007516C6: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304== 
==2304== 32 bytes in 1 blocks are definitely lost in loss record 8 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1007516C6: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304== 
==2304== 48 bytes in 1 blocks are still reachable in loss record 9 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006D852B: xpc_array_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D7F85: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304== 
==2304== 48 bytes in 1 blocks are indirectly lost in loss record 10 of 38
==2304==    at 0x100157E51: malloc_zone_calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E5F2: _mapStrIsEqual(_NXMapTable*, void const*, void const*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073E57C: NXMapInsert (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073E23D: _mapStrHash(_NXMapTable*, void const*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073DFFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304== 
==2304== 64 bytes in 1 blocks are still reachable in loss record 11 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1006D859B: _xpc_calloc (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8542: xpc_array_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D7F85: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304==    by 0x10004D59F: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==2304== 
==2304== 64 bytes in 1 blocks are still reachable in loss record 12 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006EEB3A: _xpc_pipe_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8614: _xpc_create_bootstrap_pipe (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D832D: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 64 bytes in 1 blocks are indirectly lost in loss record 13 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100435FB5: _owned_ptr_alloc (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x100436675: setenv (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x1006D83E6: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304==    by 0x10004D59F: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==2304== 
==2304== 80 (32 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 14 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E14F: _NXMapMember(_NXMapTable*, void const*, void**) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073DFFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 80 (32 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 15 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E170: _NXMapMember(_NXMapTable*, void const*, void**) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073DFFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 80 (16 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100435FA3: _owned_ptr_alloc (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x100436675: setenv (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x1006D83E6: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304==    by 0x10004D59F: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==2304== 
==2304== 128 bytes in 1 blocks are definitely lost in loss record 17 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100316801: tlv_load_notification (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10004F64F: dyld::registerAddCallback(void (*)(mach_header const*, long)) (in /usr/lib/dyld)
==2304==    by 0x100315E7A: _dyld_register_func_for_add_image (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10032E41A: _dyld_initializer (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x100163780: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304== 
==2304== 128 bytes in 1 blocks are definitely lost in loss record 18 of 38
==2304==    at 0x100157FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10075A752: int sliceRequiresGC<Arch32>(Arch32::mh_t, FileSlice) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C299: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 128 bytes in 1 blocks are definitely lost in loss record 19 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x10029DBC5: _dispatch_lane_create_with_target (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006A05F5: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)
==2304==    by 0x1001637B0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304== 
==2304== 128 bytes in 4 blocks are definitely lost in loss record 20 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 128 bytes in 4 blocks are definitely lost in loss record 21 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1007516C6: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304== 
==2304== 152 bytes in 1 blocks are still reachable in loss record 22 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10032212F: tlv_allocate_and_initialize_for_key (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x100321F67: tlv_get_addr (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10000873E: std::sys_common::thread_info::THREAD_INFO::__getit (cell.rs:249)
==2304==    by 0x1000089AF: <std::thread::local::LocalKey<T>>::with (local.rs:296)
==2304==    by 0x1000027DD: std::rt::lang_start_internal (thread_info.rs:37)
==2304==    by 0x1000018B1: std::rt::lang_start (in ./main)
==2304==    by 0x100001971: main (in ./main)
==2304== 
==2304== 252 bytes in 2 blocks are indirectly lost in loss record 23 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1006D8CA6: _xpc_malloc (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8B81: _xpc_dictionary_insert (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8F27: _xpc_dyld_image_callback (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x10004F8DA: dyld::registerBulkLoadCallback(void (*)(unsigned int, mach_header const**, char const**)) (in /usr/lib/dyld)
==2304==    by 0x1006D8DBA: _xpc_collect_images (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8337: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 288 bytes in 6 blocks are indirectly lost in loss record 24 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006F4D46: _xpc_string_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D88CF: xpc_dictionary_set_string (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8725: _xpc_collect_environment (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8332: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 300 bytes in 6 blocks are indirectly lost in loss record 25 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1006D8CA6: _xpc_malloc (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8B81: _xpc_dictionary_insert (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D88E0: xpc_dictionary_set_string (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8725: _xpc_collect_environment (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8332: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 348 (96 direct, 252 indirect) bytes in 1 blocks are definitely lost in loss record 26 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006D8877: xpc_dictionary_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8EA2: _xpc_dyld_image_callback (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x10004F8DA: dyld::registerBulkLoadCallback(void (*)(unsigned int, mach_header const**, char const**)) (in /usr/lib/dyld)
==2304==    by 0x1006D8DBA: _xpc_collect_images (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8337: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 352 bytes in 4 blocks are indirectly lost in loss record 27 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073C049: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 440 (88 direct, 352 indirect) bytes in 1 blocks are definitely lost in loss record 28 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073C049: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 925 bytes in 6 blocks are indirectly lost in loss record 29 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10042DCE5: strdup (in /usr/lib/system/libsystem_c.dylib)
==2304==    by 0x1006D88FD: xpc_string_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D88CF: xpc_dictionary_set_string (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8725: _xpc_collect_environment (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8332: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 1,536 bytes in 1 blocks are definitely lost in loss record 30 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073BCBA: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F0B3: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==2304==    by 0x10004D59F: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==2304== 
==2304== 1,609 (96 direct, 1,513 indirect) bytes in 1 blocks are definitely lost in loss record 31 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100740667: objc_msgSend_stret (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298FEC: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1006D8877: xpc_dictionary_create (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D86F9: _xpc_collect_environment (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1006D8332: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==2304==    by 0x1001637A0: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x1000665ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304==    by 0x10006100A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x100060F75: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304==    by 0x10005F013: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==2304== 
==2304== 1,632 bytes in 51 blocks are definitely lost in loss record 32 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 1,632 bytes in 51 blocks are definitely lost in loss record 33 of 38
==2304==    at 0x100157C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x1007515F3: objc::DenseMap<objc_class*, objc_class*, objc::DenseMapValueInfo<objc_class*>, objc::DenseMapInfo<objc_class*>, objc::detail::DenseMapPair<objc_class*, objc_class*> >::grow(unsigned int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1007516C6: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 2,048 bytes in 1 blocks are still reachable in loss record 34 of 38
==2304==    at 0x100157635: malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x100757E95: class_setWeakIvarLayout (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100757E26: class_setWeakIvarLayout (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075BBF9: _objc_atfork_parent (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100749742: property_copyAttributeList (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073F1E7: NXMapRemove (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100751BD2: attachCategories(objc_class*, locstamped_category_t const*, unsigned int, int) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1007516C6: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10075169F: objc_class::mangledName() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D406: objc_opt::objc_stringhash_t::getIndex(char const*) const (in /usr/lib/libobjc.A.dylib)
==2304== 
==2304== 2,064 bytes in 1 blocks are indirectly lost in loss record 35 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073E0B5: getProtocol(char const*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== 2,064 bytes in 1 blocks are indirectly lost in loss record 36 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073F01E: NXMapRemove (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073EEA5: search_method_list(method_list_t const*, objc_selector*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073D0DD: _getObjc2MessageRefs(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 2,088 (24 direct, 2,064 indirect) bytes in 1 blocks are definitely lost in loss record 37 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073DFCC: protocols() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073E959: prepareMethodLists(objc_class*, method_list_t**, int, bool, bool) (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073CEF6: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304== 
==2304== 2,120 (24 direct, 2,096 indirect) bytes in 1 blocks are definitely lost in loss record 38 of 38
==2304==    at 0x1001578AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2304==    by 0x10073DFCC: protocols() (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10073C96E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x10074D2D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x1000505A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==2304==    by 0x100050746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==2304==    by 0x100316AD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==2304==    by 0x10073BDAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==2304==    by 0x100298F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x1002A50E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==2304==    by 0x100163790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==2304==    by 0x1000661E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==2304== 
==2304== LEAK SUMMARY:
==2304==    definitely lost: 5,976 bytes in 126 blocks
==2304==    indirectly lost: 6,437 bytes in 31 blocks
==2304==      possibly lost: 0 bytes in 0 blocks
==2304==    still reachable: 2,390 bytes in 6 blocks
==2304==         suppressed: 0 bytes in 0 blocks
==2304== 
==2304== For lists of detected and suppressed errors, rerun with: -s
==2304== ERROR SUMMARY: 20 errors from 20 contexts (suppressed: 1 from 1)
~/leak ❯ 

@workingjubilee
Copy link
Member

workingjubilee commented Oct 6, 2021

Is this report about leakages that could lead to unconstrained memory usage or just memory that was allocated for the entire lifespan of the process on purpose? Based on what I have been reading, Valgrind does not fully differentiate between the two, and only seems to sense bytes that have not been deliberately cleaned up at the end, but we should expect perpetual allocation in some cases, and that leaving it to the system can actually be better than bothering to run a destructor if the destructor was trivial, thus consuming active program cycles before termination even when it would be equally safe to leave it to the system. Even OWASP mentions this is not a problem in short-lived userland applications.

According to the Valgrind FAQ, for the "still reachable" 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.

I am puzzled by the last report here, since it is actually quite severe by comparison, but it seems all the leaks detected are actually inside MacOS libraries and thus things we cannot do much about.

bors bot added a commit to godot-rust/gdext that referenced this issue Feb 26, 2023
133: Fix use-after-free and 3 memory leaks; enforce AddressSanitizer in CI r=Bromeon a=Bromeon

Changes implementation of the `Gd` smart pointer to cache the instance ID in each object. To my knowledge, instance IDs are the only reliable way to check for object validity in Godot, as raw object pointers may become dangling.

In addition, this PR fixes 3 memory leaks around arrays and dictionaries. Those occurred due to `from_sys_init()` using `T::default()` in too many places. This essentially lead to allocating a default-constructed object, which is then immediately overwritten by the `init` function, which _also_ allocates a new object. I refactored the `GodotFfi::from_sys_init()` to **never** call `default()`, and add an explicit `from_sys_init_default()` for cases where this is desired. This also cuts down on some of the boilerplate.

---

Both use-after-free and memory leaks were discovered using AddressSanitizer/LeakSanitizer. Great tooling from the C++ world, which also proves useful for us, as miri can't be used in FFI contexts. From now on, UB or leaks detected by ASan/LSan will cause a hard error in CI. The tools are not 100% bullet-proof; they didn't detect the following UAF case in a short test, but they are still of great value as a more systematic counter to memory errors.

<details><summary>use-after-free, false negative</summary>

```rs
let mut boks = Box::new(44);
let ptr = std::ptr::addr_of_mut!(*boks);
println!("deref={}", unsafe { *ptr }); // output: deref=44
drop(boks);
println!("deref={}", unsafe { *ptr }); // output: deref=1719666059
```

</details>

On a side note, getting these working correctly in CI was a bit of a marathon because ASan/LSan don't have stacktraces for dynamically loaded libraries (a known wontfix problem, see google/sanitizers#89). Additionally, false positives for memory leaks were reported: a simple `println!` would cause 1024 bytes of non-reclaimable memory. Therefore, I had to compile a special version of nightly Godot that disables dynamic library unloading via `dlclose`, to keep the stacktrace around, and this seemed to fix the false-positive issue as well. Although likely unrelated, what I also found during research was rust-lang/rust#19776.

Fixes #89.

Co-authored-by: Jan Haller <[email protected]>
@istankovic
Copy link
Contributor

Seems there are no leaks on my 64-bit Linux machine with rustc 1.75.0-nightly (249624b 2023-10-20):

$ valgrind --leak-check=full --show-reachable=yes ./a        
==19775== Memcheck, a memory error detector                                 
==19775== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.   
==19775== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==19775== Command: ./a                                                      
==19775==                                                                   
Hello World!                                                                
How are you today                                                           
==19775==                                                                   
==19775== HEAP SUMMARY:                                                     
==19775==     in use at exit: 0 bytes in 0 blocks                           
==19775==   total heap usage: 11 allocs, 11 frees, 3,181 bytes allocated    
==19775==                                                                   
==19775== All heap blocks were freed -- no leaks are possible               
==19775==                                                                   
==19775== For lists of detected and suppressed errors, rerun with: -s       
==19775== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)    

@inancgumus would you be willing to test once more on your machine with nightly rustc?

@mati865
Copy link
Contributor

mati865 commented Oct 23, 2023

I think Valgrind version might be more important than Rustc version.

@workingjubilee
Copy link
Member

Thank you @istankovic.

Then, considering also what @mati865 said, I think it is safe to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests