Randomly a segmentation fault for uninitialized TTree

Randomly I get a segmentation fault seemingly reading a TTree from TFile, that is the sign of an uninitialized object. According to valgrind, it is a TTree.
I enclose an extract of a huge code. It compiles on my mac.
The complete code makes a lot of graphs and uses minuit and so on: it performs everything, but after it is done, suddenly produces a segmentation fault.
I would appreciate any help.
Thanks a lot,
Ignazio
(I have a makefile that I am not able to upload, I do not know why)

prova.h (4.8 KB) prova.cpp (12.2 KB) makeProva.cpp (1.7 KB) makeTree.root (211.4 KB)


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.12/06
Platform: MacOS Catalina 10.15.7
Compiler: g++


At least, make sure that you initilalize all pointers in the beginning of the class constructor:

data_ = 0; // 0 ... or ... new std::string()
stato_ = 0; // 0 ... or ... new std::string()
denominazione_regione_ = 0; // 0 ... or ... new std::string()

BTW. In the class destructor, you should then add (just to quiet the valgrind):

delete file_; // automatically deletes the "tree_", too
delete data_;
delete stato_;
delete denominazione_regione_;

I have just tried because one never knows, but it is not it, of course: valgrind always indicates the TFile and the TTree as the origin of the problem.

When running valgrind, do remember to use:

--suppressions=`root-config --etcdir`/valgrind-root.supp

OK, thank you

Maybe not relevant, but i would initialize all pointers you have as private member in analysis to nullptr, and check if they are not null to delete them at destruction. If the code segfault randomly i suspect something might go wrong in the destructor of the class and the TFile which remains in an unkown status

@RENATO_QUAGLIANI In C++, you can safely execute “delete pointer;” regardless if the “pointer” is null / zero or not (if it is not null / zero, it must point to some previously allocated memory, of course).

1 Like

Yes, indeed. i commented because i saw similar random segfaults when dealing with classes storing some pointers to TFiles or TTree as private members.

Hi,
can you please attach the full valgrind log (when running with the suppressions @Wile_E_Coyote suggested)?

Cheers,
Enrico

So I have something that is nothing but what makeClass would do.
Enclosed is everything, included the valgrind output.mini.tgz (841.4 KB)

Hi,
thank you very much, I think you are running valgrind without the suppressions mentioned above, so there are a lot of false positives in the valgrind log. I’ll take a look at the reproducer.

This was the command:

light:MINI lazi$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --track-origins=yes --suppressions=`root-config --etcdir`/valgrind-root.supp ./makeMini 2&> Valgrind.output

Sorry, I confused files: I will upload the correct things soon!
Sorry!

valgrind --suppressions=root-config --etcdir/valgrind-root.supp --tool=memcheck --leak-check=yes --track-origins=yes ./makeMini 2&> Valgrind.output

Attached is the correct stuffmini_correct_one.tgz (274.2 KB)

Hi,
the valgrind output is somehow still without the suppressions I’m afraid :sweat_smile:
If the suppressions worked, you not see is entries such as the following:

==51169== Conditional jump or move depends on uninitialised value(s)                                                    
==51169==    at 0x10059A627: TUrl::TUrl(char const*, bool) (in /Applications/root_v6.12.06/lib/libCore.so)              
==51169==    by 0x100580F1C: TSystem::FindHelper(char const*, void*) (in /Applications/root_v6.12.06/lib/libCore.so)    
==51169==    by 0x1006453E9: TUnixSystem::AccessPathName(char const*, EAccessMode) (in /Applications/root_v6.12.06/lib/libCore.so)
==51169==    by 0x100642537: DylibAdded(mach_header const*, long) (in /Applications/root_v6.12.06/lib/libCore.so)       
==51169==    by 0x100054711: dyld::registerAddCallback(void (*)(mach_header const*, long)) (in /usr/lib/dyld)           
==51169==    by 0x101E84E7A: _dyld_register_func_for_add_image (in /usr/lib/system/libdyld.dylib)                       
==51169==    by 0x100642072: TUnixSystem::Init() (in /Applications/root_v6.12.06/lib/libCore.so)                        
==51169==    by 0x1004B0D34: TROOT::InitSystem() (in /Applications/root_v6.12.06/lib/libCore.so)                        
==51169==    by 0x1004AF36A: TROOT::TROOT(char const*, char const*, void (**)()) (in /Applications/root_v6.12.06/lib/libCore.so)
==51169==    by 0x1004AE158: ROOT::Internal::GetROOT1() (in /Applications/root_v6.12.06/lib/libCore.so)           

I ran makeMini in a loop 100+ times with ROOT v6.22/06 and a few times with ROOT master, and I did not observe any crash. I also ran it through valgrind (both for ROOT master and v6.22/06) and did not see any error or warning in either case. That’s without --leak-check=yes, because we are looking for invalid memory accesses rather than leaks and because --leak-check=yes introduces more false positives.

So I can’t observe the issue nor I can tell what’s wrong from the code itself.
It would be great if you could reproduce the crash on lxplus, possibly in a public directory, so we can debug the same thing.

Alternatively, you can compile your program with debug symbols (telling the makefile to add -g to the compilation flags) and run it within a debugger to see what goes wrong (see e.g. this gdb tutorial).

Sorry I can’t be of more help!
Enrico

EDIT: I see now that you are on ROOT 6.12. That’s an old version, I would strongly recommend to upgrade to v6.22/06.

The root version is the issue I am considering, being sure that that the problem is NOT in my code. In fact I just used “brew" and installed 6.22 version.
I will see later and let you know.
Thanks a lot,
Ignazio

PS So "–suppressions=root-config --etcdir/valgrind-root.supp” looks ineffective!

Grrrrrr! No, no, no!!!
I installed 6.22 version and successfully compiled, BUT…

lazi@light MINI % ./makeMini
57TTree not found!

WHAT IS THIS “57TTREE” ???
Grrrrrrrrrr!!!
Ignazio

It might be that the suppression file that comes with v6.12 is too old.

:sweat_smile:

Just checking the obvious, did you change the Makefile lines that contain paths to the ROOT installation?

Otherwise: what line prints “57” and what line prints “TTree not found!”? (I assume it’s two separate printouts garbled together)

cout << __LINE__ << "TTree not found!" << endl ;