I attached a code which compiles but it crashes when I execute it. If you look at the code, you will see there are 2 blocks of code. The 2 blocks are identical. However, when I run the code, the first block works while the second block crashes.
I think the problem comes from the fact that I rename my TChain objects. Why?
start first block
end first block
start second block
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007f1d34ab0dbc in waitpid () from /lib64/libc.so.6
#1 0x00007f1d34a33cc2 in do_system () from /lib64/libc.so.6
#2 0x00007f1d38de9dff in TUnixSystem::StackTrace (this=0x12cb980) at ../core/unix/src/TUnixSystem.cxx:2412
#3 0x00007f1d38dec52c in TUnixSystem::DispatchSignals (this=0x12cb980, sig=kSigSegmentationViolation) at ../core/unix/src/TUnixSystem.cxx:3643
#4 <signal handler called>
#5 0xfffffffffffffff8 in ?? ()
#6 0x00007f1d38d6078d in TList::FindObject (this=<optimized out>, obj=0x2fcb9a0) at ../core/cont/src/TList.cxx:614
#7 0x00007f1d38d5e07d in THashList::RecursiveRemove (this=0x12e8ce0, obj=0x2fcb9a0) at ../core/cont/src/THashList.cxx:328
#8 0x00007f1d38c54343 in TROOT::RecursiveRemove (this=0x7f1d390eee00 <ROOT::Internal::GetROOT1()::alloc>, obj=<optimized out>) at ../core/base/src/TROOT.cxx:2440
#9 0x00007f1d38cfd2a2 in CallRecursiveRemoveIfNeeded (obj=...) at include/TROOT.h:387
#10 TNamed::~TNamed (this=0x2fcb9a0, __in_chrg=<optimized out>) at ../core/base/src/TNamed.cxx:45
#11 0x00007f1d370e98a9 in TTree::~TTree (this=0x2fcb9a0, __in_chrg=<optimized out>) at ../tree/tree/src/TTree.cxx:958
#12 0x00007f1d38d6530f in TList::Delete (this=this
entry=0x2d03030, option=<optimized out>, option
entry=0x7f1d386742d9 "") at ../core/cont/src/TList.cxx:534
#13 0x00007f1d38d5e68c in THashList::Delete (this=0x2d03030, option=<optimized out>) at ../core/cont/src/THashList.cxx:215
#14 0x00007f1d38504649 in TDirectoryFile::Close (this=0x2d65af0, option=<optimized out>) at ../io/io/src/TDirectoryFile.cxx:577
#15 0x00007f1d3851e50c in TFile::Close (this=this
entry=0x2d65af0, option=option
entry=0x7f1d386742d9 "") at ../io/io/src/TFile.cxx:953
#16 0x00007f1d3851e8f1 in TFile::~TFile (this=0x2d65af0, __in_chrg=<optimized out>) at ../io/io/src/TFile.cxx:547
#17 0x00007f1d3851eb59 in TFile::~TFile (this=0x2d65af0, __in_chrg=<optimized out>) at ../io/io/src/TFile.cxx:584
#18 0x00007f1d370b960c in TChain::~TChain (this=0x2fbc270, __in_chrg=<optimized out>) at ../tree/tree/src/TChain.cxx:199
#19 0x00007f1d370b9799 in TChain::~TChain (this=0x2fbc270, __in_chrg=<optimized out>) at ../tree/tree/src/TChain.cxx:215
#20 0x000000000040125c in main ()
===========================================================
It looks like the two deletes are trying to remove the same object from an internal list, and the second time it fails. This looks like a bug, but I will let @pcanal comment on it.
If you allocate both TChain on the stack instead of on the heap, the program finishes with no error.
The problem does NOT appear in ROOT 5.34 (I tried a fairly new “v5-34-00-patches” branch).
The problem is visible in ROOT 6, however.
I tried 6.12/06 and 6.13/02:
but the valgrind step produces 170 kB long list of ROOT related errors / warnings (a usual problem with recent ROOT 6 about which I complained many times) so it’s not really possible to “debug” it.
But I maybe found a “brutal fix”:
#include "TApplication.h"
#include "TChain.h"
#include <iostream>
int main (int /*argc*/, char** /*argv*/) {
TApplication a("a", 0, 0); // just to make sure that the autoloading of ROOT libraries works
TChain *TC;
// ...
I tried the “brutal fix” of Wile_E_Coyote. It does not help.
May I expect a bug fix for future versions of ROOT? Or should I try to find some work-around? I think I can make it work if I don’t rename the TChain objects.
Indeed the problem is linked to changing the name.
TChains objects are recorded in 3 hashlist, include the LIstOfCleanups. Those hash list are basing their lookup on the name. However TChain is missing the overload of SetName that would inform those list of the changes.
When the TChain then attempt to deregister itself from the list, the lookup fails (hash is different) and hence subsequent use of the list (in particular the ListOfCleanups) leads to random behaviors. This shall be fixed shortly.
If the ‘easy’ workaround (don’t call SetName on the chain) is not practical you can use: