Segmentation violation when making an array-type branch using MyClass::Loop()

I am trying to create a new array-type branch for TTree (tree). When I just declare an array-type branch, and then run the code, and then draw the branch or access the branch in TBrowser, I get segmentation error. If I just declare a normal branch (without array), it is normal.

This is the file test.C generated by tree->MakeClass(“test”). I just add two lines to make an empty branch.

#define test_cxx
#include "test.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>

void test::Loop()
{
//   In a ROOT session, you can do:                                                                                                         
//      root> .L test.C                                                                                                                     
//      root> test t                                                                                                                        
//      root> t.GetEntry(12); // Fill t data members with entry number 12                                                                   
//      root> t.Show();       // Show values of entry 12                                                                                    
//      root> t.Show(16);     // Read and show values of entry 16                                                                           
//      root> t.Loop();       // Loop on all entries                                                                                        
//                                                                                                                                          

//     This is the loop skeleton where:                                                                                                     
//    jentry is the global entry number in the chain                                                                                        
//    ientry is the entry number in the current Tree                                                                                        
//  Note that the argument to GetEntry must be:                                                                                             
//    jentry for TChain::GetEntry                                                                                                           
//    ientry for TTree::GetEntry and TBranch::GetEntry                                                                                      
//                                                                                                                                          
//       To read only selected branches, Insert statements like:                                                                            
// METHOD1:                                                                                                                                 
//    fChain->SetBranchStatus("*",0);  // disable all branches                                                                              
//    fChain->SetBranchStatus("branchname",1);  // activate branchname                                                                      
// METHOD2: replace line                                                                                                                    
//    fChain->GetEntry(jentry);       //read all branches                                                                                   
//by  b_branchname->GetEntry(ientry); //read only this branch                                                                               
   if (fChain == 0) return;

   Double_t p1[64]; fChain->Branch("p1",&p1,"p1[64]/D"); //!!!!! added

   Long64_t nentries = fChain->GetEntriesFast();

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=23; jentry<24;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;                                                                                                     
      fChain->Fill(); //!!!! added
   }
}

This is the seg error message.

root [2] test m
(test &) @0x7f2998bfd000
root [3] m.Loop()
root [4] TBrowser gg
(TBrowser &) Name: Browser Title: ROOT Object Browser
root [5] 
 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f29aee894fc in waitpid () from /lib64/libc.so.6
#1  0x00007f29aee06fb2 in do_system () from /lib64/libc.so.6
#2  0x00007f29aff49404 in TUnixSystem::StackTrace() () from /home/daq/root_v6.22.08_gcc48/lib/libCore.so.6.22
#3  0x00007f29aff4b09a in TUnixSystem::DispatchSignals(ESignals) () from /home/daq/root_v6.22.08_gcc48/lib/libCore.so.6.22
#4  <signal handler called>
#5  0x0000000000000578 in ?? ()
#6  0x0000000005abcca8 in ?? ()
#7  0x0000000000000012 in ?? ()
#8  0x00007fff3faa4c40 in ?? ()
#9  0x00007fff3faa4d00 in ?? ()
#10 0x00007fff3faa4c30 in ?? ()
#11 0x0000000005a5cab0 in ?? ()
#12 0x0000000005ab7bf8 in ?? ()
#13 0x0000000000000025 in ?? ()
#14 0x00000000011cd938 in ?? ()
#15 0x0000000005ab3410 in ?? ()
#16 0x0000000005abd939 in ?? ()
#17 0x00007fff3faa4b1f in ?? ()
#18 0x00007fff3faa4b20 in ?? ()
#19 0x0000000005787110 in ?? ()
#20 0x0000000000000010 in ?? ()
#21 0x00007f29af96b0e5 in operator new(unsigned long) () at ../../.././libstdc++-v3/libsupc++/new_op.cc:50
#22 0x00007f29ab617c94 in cling::IncrementalJIT::getSymbolAddressWithoutMangling(std::string const&, bool) () from /home/daq/root_v6.22.08_gcc48/lib/libCling.so
#23 0x00007fff3faa4f30 in ?? ()
#24 0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum https://root.cern.ch/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at https://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  0x0000000000000578 in ?? ()
#6  0x0000000005abcca8 in ?? ()
#7  0x0000000000000012 in ?? ()
#8  0x00007fff3faa4c40 in ?? ()
#9  0x00007fff3faa4d00 in ?? ()
#10 0x00007fff3faa4c30 in ?? ()
#11 0x0000000005a5cab0 in ?? ()
#12 0x0000000005ab7bf8 in ?? ()
#13 0x0000000000000025 in ?? ()
#14 0x00000000011cd938 in ?? ()
#15 0x0000000005ab3410 in ?? ()
#16 0x0000000005abd939 in ?? ()
#17 0x00007fff3faa4b1f in ?? ()
#18 0x00007fff3faa4b20 in ?? ()
#19 0x0000000005787110 in ?? ()
#20 0x0000000000000010 in ?? ()
#21 0x00007f29af96b0e5 in operator new(unsigned long) () at ../../.././libstdc++-v3/libsupc++/new_op.cc:50
#22 0x00007f29ab617c94 in cling::IncrementalJIT::getSymbolAddressWithoutMangling(std::string const&, bool) () from /home/daq/root_v6.22.08_gcc48/lib/libCling.so
#23 0x00007fff3faa4f30 in ?? ()
#24 0x0000000000000000 in ?? ()
===========================================================

Thank you,
Marco


ROOT Version: 6.22/08
Platform: centos 7
Compiler: aclic


Hi Marco,

Welcome to the ROOT forum!

Since the new branch needs to “catch up” with the already written entries, I think you’d need to call BackFill() on the branch instead of fChain->Fill().

You get the TBranch * as a result of fChain->Branch(...).

Cheers,
Jakob

Hi Jakob,

Thank you for your reply. Do you mean that I should put this kind of code to backfill all existing and new branches instead of fChain->Fill()?

for( auto e = 0; e < fChain->GetEntries(); ++e ) { // loop over entries.
  for( auto branch : branchCollection) {
     ... Make change to the data associated with the branch ...
     branch->BackFill();
  }
}

But I am not sure how to create branchCollection and modify Make change to the data associated with the branch. If possible, could you please explain? Thank you!

Best regards,
Marco

Not having tested this myself yet, but looking into your code sample, I would try with

Double_t p1[64]; 
auto newBranch = fChain->Branch("p1",&p1,"p1[64]/D");

and then later

newBranch->BackFill();

(By the way, perhaps this has just been cut out of the example, but I guess in the actual code you have some content for p1? So, if the tree already has 100 events, in the event loop you are going to fill 100 times the p1 array with some values based on the existing data of the event?)

I tried your suggestion. But it did not work. (segmentation violation again)

(Yes, you are right. )

In the end of your “Loop” method, try to add:
fChain->ResetBranchAddresses(); // disconnect from local variables

That said, the TTree::MakeClass generated analysis skeleton opens the ROOT file in “READ” mode. So, expect problems when you try to modify the tree in your “Loop” method.

Sorry. There is a mistake in the code.
I should loop over all entries instead of the 23rd event.

#define test_cxx
#include "test.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>

void test::Loop()
{
//   In a ROOT session, you can do:                                                                                                         
//      root> .L test.C                                                                                                                     
//      root> test t                                                                                                                        
//      root> t.GetEntry(12); // Fill t data members with entry number 12                                                                   
//      root> t.Show();       // Show values of entry 12                                                                                    
//      root> t.Show(16);     // Read and show values of entry 16                                                                           
//      root> t.Loop();       // Loop on all entries                                                                                        
//                                                                                                                                          

//     This is the loop skeleton where:                                                                                                     
//    jentry is the global entry number in the chain                                                                                        
//    ientry is the entry number in the current Tree                                                                                        
//  Note that the argument to GetEntry must be:                                                                                             
//    jentry for TChain::GetEntry                                                                                                           
//    ientry for TTree::GetEntry and TBranch::GetEntry                                                                                      
//                                                                                                                                          
//       To read only selected branches, Insert statements like:                                                                            
// METHOD1:                                                                                                                                 
//    fChain->SetBranchStatus("*",0);  // disable all branches                                                                              
//    fChain->SetBranchStatus("branchname",1);  // activate branchname                                                                      
// METHOD2: replace line                                                                                                                    
//    fChain->GetEntry(jentry);       //read all branches                                                                                   
//by  b_branchname->GetEntry(ientry); //read only this branch                                                                               
   if (fChain == 0) return;

   Double_t p1[64];
   auto b_p1 = fChain->Branch("p1",&p1,"p1[64]/D");

   Long64_t nentries = fChain->GetEntriesFast();

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;                                                                                                     
      //fChain->Fill();                                                                                                                     
      b_p1->BackFill();
   }
   //fChain->ResetBranchAddresses();                                                                                                        
}

With the BackFill() method, the outcome is segmentation error when executing Loop().

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::TBranch::Fill>: Failed to write out basket.

Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.
Error in <TBranch::WriteBasketImpl>: basket's WriteBuffer failed.

And it occurred recursively (probably for each loop).

With the addition of ResetBranchAddresses() at the end. The outcome is the same.

It seems it is difficult to solve the problem. So I think I will try to make the root files with “existing” branches and additional branch in the same code.

Thank you everyone.

That is always the best. The code structure you use (MakeClass with a chain) is defaulting to opening the file read-only, so you can not update them. In addition, back filling a chain is “harder” than usual since it will need to open a series of files. A better alternative (to updating the files) is to create a new file and a new TTree that will later be added to the chain as a friend (see TTree::AddFriend)

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