TTree->GetEntry() crashes in ROOT6, not in 5.34, and only when running a macro

Hello,

My problem seems to be same as described in this topic :

But it had no answer and the thread is about one year old.

I want to extract data from a .root file using tree->GetEntry() (after setting the branch adresses and everything), which works fine with ROOT 5.34/25, but it crashes when I try to run my macro with ROOT 6.04/14. What’s even weirder is that I can run an interactive session in ROOT6, copy and paste every command line, and the code will run smoothly, without any exception raised.

I believe this has something to do with the class of the objects in my branches. I have objects like map<int, vector<double> >; map<int, vector<pair<double, double> > >; and other “custom” classes. Every tree that contains these objects crashes when I try to GetEntry(), but I know the tree is correctly loaded as I can Print() or GetEntries() without any problem.

There is a LinkDef file where these classes are defined and I load it through a .so file using R__LOAD_LIBRARY(libTOTCalib) (or gSystem->Load("libTOTCalib.so") for ROOT5). Perhaps the library or the Makefile is not compatible with ROOT6, as I’ve seen few things about Cint, but I believe ROOT6 uses Cling now. However, I would like my code to be compatible with both versions (for distribution).

Here is the beginning of my macro :

#include <TH2I.h>
#include <TString.h>
#include <TROOT.h>
#include <TSystem.h>
#include "TObject.h"

#include <vector>
#include <string>

#include <map>
#include <iostream>
#include <TFitResultPtr.h>
#include <TFitResult.h>
#include "TExec.h"

R__LOAD_LIBRARY(libTOTCalib);

using namespace std;

void runAnalysis(){

	// Load ROOT file and link branches to variables

	TString file = "GaAs500.root";
	TFile * f = new TFile(file.Data());
	TTree * tsurr = (TTree *) f->Get("surrogateFunction"); //first tree in file; contains 2 branches

	map< int, vector< double > > * surr_p;
	map< int, int > * surr_status;
	tsurr->SetBranchAddress("parameters", &surr_p);
	tsurr->SetBranchAddress("status", &surr_status);
	tsurr->Print(); //works!
	tsurr->GetEntry(0); // this TTree has a single entry, it crashes here

	//Other stuff that doesn't run because ROOT crashed
}

And here is the exception raised (not very helpful to me):

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f2fe0e7827c in __libc_waitpid (pid=174872, stat_loc=stat_loc
entry=0x7fff5da83320, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:31
#1  0x00007f2fe0dfbc72 in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2  0x00007f2fe1e89c5a in TUnixSystem::StackTrace() () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
#3  0x00007f2fe1e8bc2c in TUnixSystem::DispatchSignals(ESignals) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
#4  <signal handler called>
#5  0x00007f2fd4e8c015 in ROOT::TCollectionProxyInfo::Type<std::map<int, std::vector<double, std::allocator<double> >, std::less<int>, std::allocator<std::pair<int const, std::vector<double, std::allocator<double> > > > > >::clear(void*) () from /export/home/zp/roux/github/mafalda/TOTCalib/libTOTCalib.so
#6  0x00007f2fdd7ea0a9 in TGenCollectionStreamer::ReadBufferGeneric(TBuffer&, void*, TClass const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#7  0x00007f2fdd924f29 in TBufferFile::ReadFastArray(void*, TClass const*, int, TMemberStreamer*, TClass const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#8  0x00007f2fdd866526 in int TStreamerInfoActions::ReadSTL<&TStreamerInfoActions::ReadSTLMemberWiseSameClass, &TStreamerInfoActions::ReadSTLObjectWiseFastArray>(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#9  0x00007f2fdd923ac5 in TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#10 0x00007f2fd40b3159 in TBranchElement::ReadLeavesMember(TBuffer&) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#11 0x00007f2fd4093822 in TBranch::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#12 0x00007f2fd40beae1 in TBranchElement::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#13 0x00007f2fd406da33 in TTree::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#14 0x00007f2fe245611f in ?? ()
#15 0x0000000004a94bb3 in ?? ()
#16 0x0000000000000007 in ?? ()
#17 0x0000000006246fa8 in ?? ()
#18 0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007f2fd4e8c015 in ROOT::TCollectionProxyInfo::Type<std::map<int, std::vector<double, std::allocator<double> >, std::less<int>, std::allocator<std::pair<int const, std::vector<double, std::allocator<double> > > > > >::clear(void*) () from /export/home/zp/roux/github/mafalda/TOTCalib/libTOTCalib.so
#6  0x00007f2fdd7ea0a9 in TGenCollectionStreamer::ReadBufferGeneric(TBuffer&, void*, TClass const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#7  0x00007f2fdd924f29 in TBufferFile::ReadFastArray(void*, TClass const*, int, TMemberStreamer*, TClass const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#8  0x00007f2fdd866526 in int TStreamerInfoActions::ReadSTL<&TStreamerInfoActions::ReadSTLMemberWiseSameClass, &TStreamerInfoActions::ReadSTLObjectWiseFastArray>(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#9  0x00007f2fdd923ac5 in TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRIO.so
#10 0x00007f2fd40b3159 in TBranchElement::ReadLeavesMember(TBuffer&) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#11 0x00007f2fd4093822 in TBranch::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#12 0x00007f2fd40beae1 in TBranchElement::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#13 0x00007f2fd406da33 in TTree::GetEntry(long long, int) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libTree.so
#14 0x00007f2fe245611f in ?? ()
#15 0x0000000004a94bb3 in ?? ()
#16 0x0000000000000007 in ?? ()
#17 0x0000000006246fa8 in ?? ()
#18 0x0000000000000000 in ?? ()
===========================================================

Attached you will also find my test root file, the Makefile and the LinkDef. Notice how these last two mention rootcint, but not rootcling. Should they be modified to be compatible with both versions?

(I had to add an extension to the Makefile to upload it)

Thanks for your help.
Jasmeru
GaAs500.root (6.3 KB)
TOTCalib_LinkDef.h (619 Bytes)
Makefile.c (956 Bytes)

This is undefined behaviour. You need to initialize your variables properly. Either set them to nullptr or create the object using new. Easiest way is to add = nullptr like so:

	map< int, vector< double > > * surr_p = nullptr;
	map< int, int > * surr_status = nullptr;
	tsurr->SetBranchAddress("parameters", &surr_p);
	tsurr->SetBranchAddress("status", &surr_status);
2 Likes

Thanks! I would never have thought the solution was so easy.

Any idea why this wasn’t an issue in ROOT 5.34, or even in a ROOT6 interactive session?

Jasmeru

Maybe it is a ROOT extension to initialize variables?
Initialization is quite a complex topic, there are even multiple types of it (zero-, default-, value-initialization, …) I don’t know what interactive root is doing here.

Anyway, in regular C++ a pod variable that isn’t static or declared at global scope (which your variables aren’t) is not initialized (approximately correct - there are differences between C++98 and C++11 (at least for non-pod classes), for all glory details see section 8.5 (decl.init) of the standard - at least I assume it’s there…). Just initialize all variables unless you know it is done automatically.

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