Memory leaks on examples

Hello,

I recently come to learn the existence of specific compilation flags to detect memory leaks/potentials undefined behaviors. It simply consists in setting an additional compilation flag https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html:

-fsanitize=address,undefined

I have tested it right away first on some of my code and after in the geant4 provided examples. Specifically, I have adapted the cmake compilation flags in the example B1 to include the following line:

set(CMAKE_CXX_FLAGS " -Wall -Wextra -Wpedantic -g -Og -fsanitize=address,undefined")

After compilation and execution via macro run1.mac, this is the stderr:

==7938==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 160000 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe6c8 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:98
    #1 0x72c3e8697254 in G4MTRunManager::G4MTRunManager() /home/questo/software/geant4/source/geant4-v11.2.0/source/run/src/G4MTRunManager.cc:156

Direct leak of 344 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e9779e53 in G4GMocrenMessenger::G4GMocrenMessenger() /home/questo/software/geant4/source/geant4-v11.2.0/source/visualization/gMocren/src/G4GMocrenMessenger.cc:128

Direct leak of 50 byte(s) in 50 object(s) allocated from:
    #0 0x72c3e90fe6c8 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:98
    #1 0x72c3e9738959 in G4HepRepFileXMLWriter::init() /home/questo/software/geant4/source/geant4-v11.2.0/source/visualization/HepRep/src/G4HepRepFileXMLWriter.cc:60

Indirect leak of 33 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e97ace09 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) /usr/include/c++/13/bits/basic_string.tcc:229

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e97ae8b6 in std::__new_allocator<G4String>::allocate(unsigned long, void const*) /usr/include/c++/13/bits/new_allocator.h:151
    #2 0x72c3e97ae8b6 in std::allocator_traits<std::allocator<G4String> >::allocate(std::allocator<G4String>&, unsigned long) /usr/include/c++/13/bits/alloc_traits.h:482
    #3 0x72c3e97ae8b6 in std::_Vector_base<G4String, std::allocator<G4String> >::_M_allocate(unsigned long) /usr/include/c++/13/bits/stl_vector.h:381
    #4 0x72c3e97ae8b6 in std::_Vector_base<G4String, std::allocator<G4String> >::_M_allocate(unsigned long) /usr/include/c++/13/bits/stl_vector.h:378
    #5 0x72c3e97ae8b6 in void std::vector<G4String, std::allocator<G4String> >::_M_realloc_insert<char const*&>(__gnu_cxx::__normal_iterator<G4String*, std::vector<G4String, std::allocator<G4String> > >, char const*&) /usr/include/c++/13/bits/vector.tcc:459

Indirect leak of 31 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e436870e in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x16870e) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #2 0x72c3e436982a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x16982a) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #3 0x72c3e597621a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*) /usr/include/c++/13/bits/basic_string.h:1684
    #4 0x72c3e597621a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*) /usr/include/c++/13/bits/basic_string.h:824
    #5 0x72c3e597621a in G4UIcommand::G4UIcommandCommonConstructorCode(char const*) /home/questo/software/geant4/source/geant4-v11.2.0/source/intercoms/src/G4UIcommand.cc:64

Indirect leak of 31 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e436870e in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x16870e) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #2 0x72c3e436982a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x16982a) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #3 0x72c3e59761fe in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*) /usr/include/c++/13/bits/basic_string.h:1684
    #4 0x72c3e59761fe in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*) /usr/include/c++/13/bits/basic_string.h:824
    #5 0x72c3e59761fe in G4UIcommand::G4UIcommandCommonConstructorCode(char const*) /home/questo/software/geant4/source/geant4-v11.2.0/source/intercoms/src/G4UIcommand.cc:63

Indirect leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x72c3e90fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x72c3e59759cf in void std::vector<G4ApplicationState, std::allocator<G4ApplicationState> >::_M_assign_aux<G4ApplicationState const*>(G4ApplicationState const*, G4ApplicationState const*, std::forward_iterator_tag) /usr/include/c++/13/bits/new_allocator.h:151

SUMMARY: AddressSanitizer: 160545 byte(s) leaked in 57 allocation(s).

With the enabling of the default graphic, even more memory leaks will appear.
Additionally, by testing it with a more comprehensive example, B4C with run2.mac, here is the summary:

SUMMARY: AddressSanitizer: 3393370 byte(s) leaked in 115099 allocation(s).

From what I can tell, the memory leaks appear only to a negligible amount of memory. I was wondering whether this is currently taken into account during the testing process for new releases of Geant4. Additionally, in your opinion, would it be worthwhile to include checks for memory leaks and undefined behavior as part of the pre-release testing procedures?

Thank you,
Enrico

Geant4 Version: 11.2.0
Operating System: Ubuntu 24.04.4 LTS
Compiler/Version: g++ (Ubuntu 13.3.0-6ubuntu2\~24.04) 13.3.0
CMake Version: cmake version 3.28.3


Hi Enrico,

each release of Geant4 is proofed against memory leaks in the best possible way, using the Valgrind sanitizer tool, in particular for leaks originating during the simulation run, which may lead to memory growth.

We are aware of ‘static’ leaks like those you show and mostly coming from the application, they’re less relevant and therefore considered lower priority, nevertheless they’re worth to be cleared but requiring some effort…

Cheers, Gabriele

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.