rust-cli / env_logger

A logging implementation for `log` which is configured via an environment variable.
https://docs.rs/env_logger
Apache License 2.0
803 stars 125 forks source link

Possibly not freed memory #330

Closed egaban closed 1 month ago

egaban commented 1 month ago

I was just running valgrind on my code to check for memory leaks, and apparently, there are 272 bytes still reachable at the end of the program. I've created a simple test scenario with the following main.rs:

fn main() {
    env_logger::init();
}

After running Valgrind, this is the result:

==11564== Memcheck, a memory error detector
==11564== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==11564== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==11564== Command: ./target/debug/leak_test
==11564== 
==11564== 
==11564== HEAP SUMMARY:
==11564==     in use at exit: 272 bytes in 3 blocks
==11564==   total heap usage: 13 allocs, 10 frees, 2,446 bytes allocated
==11564== 
==11564== LEAK SUMMARY:
==11564==    definitely lost: 0 bytes in 0 blocks
==11564==    indirectly lost: 0 bytes in 0 blocks
==11564==      possibly lost: 0 bytes in 0 blocks
==11564==    still reachable: 272 bytes in 3 blocks
==11564==         suppressed: 0 bytes in 0 blocks
==11564== Rerun with --leak-check=full to see details of leaked memory
==11564== 
==11564== For lists of detected and suppressed errors, rerun with: -s
==11564== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

I'm not sure if this is a problem. My env_logger version is 0.11.5

egaban commented 1 month ago

Just posting the logs with --leak-check=full:

==14682== Memcheck, a memory error detector
==14682== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==14682== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==14682== Command: ./target/debug/leak_test
==14682== 
==14682== 
==14682== HEAP SUMMARY:
==14682==     in use at exit: 272 bytes in 3 blocks
==14682==   total heap usage: 13 allocs, 10 frees, 2,446 bytes allocated
==14682== 
==14682== 40 bytes in 1 blocks are still reachable in loss record 1 of 3
==14682==    at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14682==    by 0x1522FA: alloc::alloc::alloc (alloc.rs:100)
==14682==    by 0x1523E4: alloc::alloc::Global::alloc_impl (alloc.rs:183)
==14682==    by 0x15223A: allocate (alloc.rs:243)
==14682==    by 0x15223A: alloc::alloc::exchange_malloc (alloc.rs:332)
==14682==    by 0x14D228: new<env_logger::fmt::{impl#5}::build::{closure_env#0}> (boxed.rs:259)
==14682==    by 0x14D228: env_logger::fmt::Builder::build (mod.rs:236)
==14682==    by 0x14A93E: env_logger::logger::Builder::build (logger.rs:513)
==14682==    by 0x14A6A4: env_logger::logger::Builder::try_init (logger.rs:476)
==14682==    by 0x14B3CA: env_logger::logger::try_init_from_env (logger.rs:913)
==14682==    by 0x14B359: env_logger::logger::try_init (logger.rs:863)
==14682==    by 0x14B376: env_logger::logger::init (logger.rs:876)
==14682==    by 0x1462A6: leak::main (main.rs:2)
==14682==    by 0x1461BA: core::ops::function::FnOnce::call_once (function.rs:250)
==14682== 
==14682== 104 bytes in 1 blocks are still reachable in loss record 2 of 3
==14682==    at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14682==    by 0x1522FA: alloc::alloc::alloc (alloc.rs:100)
==14682==    by 0x1523E4: alloc::alloc::Global::alloc_impl (alloc.rs:183)
==14682==    by 0x15223A: allocate (alloc.rs:243)
==14682==    by 0x15223A: alloc::alloc::exchange_malloc (alloc.rs:332)
==14682==    by 0x14A77B: new<env_logger::logger::Logger> (boxed.rs:259)
==14682==    by 0x14A77B: env_logger::logger::Builder::try_init (logger.rs:479)
==14682==    by 0x14B3CA: env_logger::logger::try_init_from_env (logger.rs:913)
==14682==    by 0x14B359: env_logger::logger::try_init (logger.rs:863)
==14682==    by 0x14B376: env_logger::logger::init (logger.rs:876)
==14682==    by 0x1462A6: leak::main (main.rs:2)
==14682==    by 0x1461BA: core::ops::function::FnOnce::call_once (function.rs:250)
==14682==    by 0x14628D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:155)
==14682==    by 0x146260: std::rt::lang_start::{{closure}} (rt.rs:159)
==14682== 
==14682== 128 bytes in 1 blocks are still reachable in loss record 3 of 3
==14682==    at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14682==    by 0x2CDBCA: alloc::alloc::alloc (alloc.rs:100)
==14682==    by 0x2CDCB4: alloc::alloc::Global::alloc_impl (alloc.rs:183)
==14682==    by 0x2CEA88: <alloc::alloc::Global as core::alloc::Allocator>::allocate (alloc.rs:243)
==14682==    by 0x25E1FA: alloc::raw_vec::finish_grow (raw_vec.rs:573)
==14682==    by 0x161D4B: alloc::raw_vec::RawVec<T,A>::grow_amortized (raw_vec.rs:485)
==14682==    by 0x162466: alloc::raw_vec::RawVec<T,A>::grow_one (raw_vec.rs:364)
==14682==    by 0x167EBE: alloc::vec::Vec<T,A>::push (mod.rs:1999)
==14682==    by 0x16350C: env_filter::filter::Builder::build (filter.rs:146)
==14682==    by 0x14A8DA: env_logger::logger::Builder::build (logger.rs:512)
==14682==    by 0x14A6A4: env_logger::logger::Builder::try_init (logger.rs:476)
==14682==    by 0x14B3CA: env_logger::logger::try_init_from_env (logger.rs:913)
==14682== 
==14682== LEAK SUMMARY:
==14682==    definitely lost: 0 bytes in 0 blocks
==14682==    indirectly lost: 0 bytes in 0 blocks
==14682==      possibly lost: 0 bytes in 0 blocks
==14682==    still reachable: 272 bytes in 3 blocks
==14682==         suppressed: 0 bytes in 0 blocks
==14682== 
==14682== For lists of detected and suppressed errors, rerun with: -s
==14682== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
epage commented 1 month ago

Not able to check the implementation atm but i think that we have to leak the logger so it has 'static lifetime so we can register it.

egaban commented 1 month ago

That makes sense, thanks for the quick answer :)