Segmentation violation when accessing TBranch array

ROOT Version: 6.24
Platform: Red Hat Enterprise Linux 7.9
Compiler: GCC 10.2.0

Dear experts,

I’m trying to open a file, make a copy of the tree it contains and fill it with a subset of the original tree’s entries. In the process I set the address of one of the branches which contains an array of variable length (although for the first entry it’s length 20). Here is a minimal example

TFile *f1 = new TFile("inFile.root");
TTree *t1 = (TTree*) f1 -> Get("tree");
TFile *f2 = new TFile("outFile.root", "RECREATE");
TTree *t2 = t1 -> CloneTree(0);

Float_t *varArray = new Float_t[20];
t1 -> SetBranchAddress("MCParticles.m_energy", varArray); //This causes the seg fault

t1 -> GetEntry(0); //Just the first entry for demonstration
t2 -> Fill();

t2 -> Write();
t2 -> AutoSave();

Trying to run this results in a segmentation violation. I’ve narrowed the cause down to the SetBranchAddress line since the macro runs fine without it.

There was a crash.
This is the entire stack trace of all threads:
#0  0x00002af65b4474fc in waitpid () from /lib64/
#1  0x00002af65b3c4f62 in do_system () from /lib64/
#2  0x00002af65a64feec in TUnixSystem::Exec (shellcmd=<optimized out>, this=0x10d6570) at /cvmfs/
#3  TUnixSystem::StackTrace (this=0x10d6570) at /cvmfs/
#4  0x00002af66e0c0cd2 in (anonymous namespace)::do_trace (sig=1) at /cvmfs/
#5  (anonymous namespace)::TExceptionHandlerImp::HandleException (this=<optimized out>, sig=1) at /cvmfs/
#6  0x00002af65a64d371 in TUnixSystem::DispatchSignals (this=0x10d6570, sig=kSigSegmentationViolation) at /cvmfs/
#7  <signal handler called>
#8  0x00002af66b65f926 in TBranchElement::FillLeavesClonesMember (this=0x10a4cdb0, b=...) at /cvmfs/
#9  0x00002af66b659d3e in TBranch::FillImpl (imtHelper=0x0, this=0x10a4cdb0) at /cvmfs/
#10 TBranch::FillImpl (this=this
entry=0x10a4cdb0, imtHelper=imtHelper
entry=0x0) at /cvmfs/
#11 0x00002af66b66635b in TBranchElement::FillImpl (this=0x10a4cdb0, imtHelper=0x0) at /cvmfs/
#12 0x00002af66b666059 in TBranchElement::FillImpl (this=0x1044c1b0, imtHelper=0x0) at /cvmfs/
#13 0x00002af66b6d08b0 in TTree::Fill (this=0x8f31d00) at /cvmfs/
#14 0x00002af65a194317 in ?? ()
#15 0x00007ffeccf1ea30 in ?? ()
#16 0x00002af65d11a929 in std::_Function_handler<llvm::Expected<unsigned long> (), llvm::orc::LazyEmittingLayer<llvm::orc::LegacyIRCompileLayer<cling::IncrementalJIT::RemovableObjectLinkingLayer, llvm::orc::SimpleCompiler> >::EmissionDeferredModule::find(llvm::StringRef, bool, llvm::orc::LegacyIRCompileLayer<cling::IncrementalJIT::RemovableObjectLinkingLayer, llvm::orc::SimpleCompiler>&)::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) () from /cvmfs/
#17 0x00002af65d0824a0 in ?? () from /cvmfs/
#18 0x00000007ccf1ea00 in ?? ()
#19 0x00002af65d0824a0 in ?? () from /cvmfs/
#20 0x20000000ccf1eb40 in ?? ()
#21 0x00002af65a194530 in ?? ()
#22 0x0000000000000000 in ?? ()

Any clues on what’s going on in this simple example?


Hi Kim,
the crash happens when calling TTree::Fill. There seems to be one branch of the output tree t2 that is badly “wired” to the corresponding address of the input tree t1. And it is likely that it’s due to that SetBranchAddress that modifies the address of "MCParticles.m_energy".

Can you try moving the CloneTree after the SetBranchAddress? If that does not help, can you please provide a minimal self-contained reproducer that we can run and debug?

cc: @pcanal


From the stack trace, it appears that the MCParticles. branch was created based on an object. Setting only the address of one of its data member, switch that branch to the MakeClass mode where the object is decomposed. This mode is (seemingly) incompatible with Cloning (at the very least because schema evolution is not fully implemented per se on the write side).

To make this work you need to access the data with either a TTreeFormula or TTreeReader or via a full object (of whatever type is stored in the branch MCParticles.).

For Enrico’s suggestion I tried moving the CloneTree line after SetBranchAddress but I found this didn’t solve the issue and resulted in the same segmentation fault.

I think I’ve managed to get it working using the TTreeReader method. Basically replacing the SetBranchAddress method with a TTreeReaderArray:

TFile *f1 = new TFile("inFile.root");
TTree *t1 = (TTree*) f1 -> Get("tree");
TFile *f2 = new TFile("outFile.root", "RECREATE");
TTree *t2 = t1 -> CloneTree(0);

TTreeReader *myReader = new TTreeReader("tree", f1);
TTreeReaderArray<Float_t> varArray(*myReader, "MCParticles.m_energy");

myReader -> Next();
printf("varArray[0] = %f\n", varArray[0]);
t2 -> Fill();

t2 -> Write();
t2 -> AutoSave();

Macro runs fine now without errors.

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