My code causes a seg fault that I am sure is the result of an initialized pointer somewhere. However, I have checked thoroughly and cannot find any pointers that are initialized improperly. Am I somehow calling fill() incorrectly?
I’ve run it through gdb and the debugger identifies the problems as being at the combdata->Fill() line, line 345. I have taken many debugging steps, the most interesting of which is commenting out any of the code that assigns anything to the tree combdata, and yet I still get a segfault.
The code otherwise functions normally until it gets to the fill line.
My code is below, any help would be greatly appreciated. Thanks in advance!
/*
Program in C to combine TPFit data and GBT data into one file based on the BCIDS
Written by Joseph Farah on June 19, 2017
Last updated by [Joseph Farah] on: [June 21, 2017]
Notes
- for some reason this code causes the root intepreter to segfault when .q is run
- if you do it (type .q) twice the problem just goes away
- how to print anythin that has type vector<int>: use * upon declaration and get
value with gbtMMFE8->at(0)
-
*/
// header imports
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include "TSystem.h"
#define TRUE 1
#define FALSE 0
// begin main function
int main( int argc, char *argv[] )
{
// check the number of args, it should be 3 for proper execution
// there will always be 4 args because the file name is the first arg
if( argc != 4 ) { std::cout << argv[0] << " needs three args" << std::endl; return 0; }
// make all the filename strings constants to use in the TFile constructor
const char* gfile = argv[1];
const char* tfile = argv[2];
const char* ofile = argv[3];
std::cout << gfile << std::endl << tfile << std::endl << ofile << std::endl;
// initialize the GBT file using TFile and using the GBT file as the argument
// create new fileobject for GBT
TFile *gbt_file_object = new TFile(gfile);
// pull the tree from the file
TTree *gbt_tree = (TTree*)gbt_file_object->Get("GBT_data");
// do the same thing now with the TPfit file
// create new file object for TPfit
TFile *tpfit_file_object = new TFile(tfile);
// pull the tpfit tree fromt he file
TTree *tpfit_tree = (TTree*)tpfit_file_object->Get("TPfit_data");
// get the number of all the entries in both of the trees
long ngbt = gbt_tree->GetEntries();
long nfit = tpfit_tree->GetEntries();
// create the output file, overwriting the old one if necessary
TFile *output_file = new TFile(ofile, "RECREATE");
// here i'm going to start creating the branches for the new file
// this is going to require me initiliazing various variables to use
// as addresses, a TTree, and the branches themsleves
int t_eventnum;
int t_cntr;
int t_timesec;
int t_timensec;
int t_bcid;
int t_mxlocal;
int t_tpfit_n;
std::vector<int> *t_tpfit_VMM = 0;
std::vector<int> *t_tpfit_CH = 0;
std::vector<int> *t_tpfit_MMFE8 = 0;
std::vector<int> *t_tpfit_BCID = 0;
// this will create the combined branches data tree
// argument setup: Branch(branchname address, leaflist)
// for vectors, use the address of the vector instead of the name
TTree *combdata = new TTree("TPcomb_data", "TPcomb_data");
combdata->Branch("EventNum", t_eventnum, "EventNum/I");
combdata->Branch("cntr", t_cntr, "cntr/I");
combdata->Branch("Time_sec", t_timesec, "Time_sec/I" );
combdata->Branch("Time_nsec", t_timensec, "Time_nsec/I");
combdata->Branch("BCID", t_bcid, "BCID/I");
combdata->Branch("mxlocal", t_mxlocal, "mxlocal/F");
combdata->Branch("tpfit_VMM", &t_tpfit_VMM);
combdata->Branch("tpfit_CH", &t_tpfit_CH);
combdata->Branch("tpfit_MMFE8", &t_tpfit_MMFE8);
combdata->Branch("tpfit_BCID", &t_tpfit_BCID);
combdata->Branch("tpfit_n",t_tpfit_n, "tpfit_n/I");
// get the addresses of all the branches in the GBT and TPFit trees
//gbt tree address declaration
int gbtTime_sec;
int gbtTime_nsec;
std::vector<int> *gbtMMFE8 = 0;
std::vector<int> *gbt_VMM = 0;
std::vector<int> *gbt_CH = 0;
std::vector<int> *gbt_BCID = 0;
// List of branches
TBranch *b_EventNum = 0; //!
TBranch *b_Time_sec = 0; //!
TBranch *b_Time_nsec = 0; //!
TBranch *b_gbt_VMM = 0; //!
TBranch *b_gbt_CH = 0; //!
TBranch *b_gbt_MMFE8 = 0; //!
TBranch *b_gbt_BCID = 0; //!
//gbt_tree->SetMakeClass(1);
// gbt_tree->SetBranchAddress("Time_sec", &gbtTime_sec);
// gbt_tree->SetBranchAddress("Time_nsec", &gbtTime_nsec);
// gbt_tree->SetBranchAddress("gbt_MMFE8", &gbtMMFE8);
// gbt_tree->SetBranchAddress("gbt_VMM", &gbt_VMM);
// gbt_tree->SetBranchAddress("gbt_CH", &gbt_CH);
// gbt_tree->SetBranchAddress("gbt_BCID", &gbt_BCID);
gbt_tree->SetBranchAddress("Time_sec", &gbtTime_sec, &b_Time_sec);
gbt_tree->SetBranchAddress("Time_nsec", &gbtTime_nsec, &b_Time_nsec);
gbt_tree->SetBranchAddress("gbt_VMM", &gbt_VMM, &b_gbt_VMM);
gbt_tree->SetBranchAddress("gbt_CH", &gbt_CH, &b_gbt_CH);
gbt_tree->SetBranchAddress("gbt_MMFE8", &gbtMMFE8, &b_gbt_MMFE8);
gbt_tree->SetBranchAddress("gbt_BCID", &gbt_BCID, &b_gbt_BCID);
//tpfit tree address declaration
int EventNum, nevent;
int tpTime_sec;
int tpTime_nsec;
int BCID, bcid;
float mxlocal, mxloc;
int tpfit_n, nhit;
int cntr, spec_cntr;
std::vector<int> *tpfit_MMFE8 = 0;
std::vector<int> *tpfit_VMM = 0;
std::vector<int> *tpfit_CH = 0;
tpfit_tree->SetBranchAddress("EventNum", &EventNum);
tpfit_tree->SetBranchAddress("Time_sec", &tpTime_sec);
tpfit_tree->SetBranchAddress("Time_nsec", &tpTime_nsec);
tpfit_tree->SetBranchAddress("BCID", &BCID);
tpfit_tree->SetBranchAddress("mxlocal", &mxlocal);
tpfit_tree->SetBranchAddress("tpfit_n", &tpfit_n);
tpfit_tree->SetBranchAddress("cntr", &cntr);
tpfit_tree->SetBranchAddress("tpfit_MMFE8", &tpfit_MMFE8);
tpfit_tree->SetBranchAddress("tpfit_VMM", &tpfit_VMM);
tpfit_tree->SetBranchAddress("tpfit_CH", &tpfit_CH);
// initialize any variables that will be used within the loop
float gbttime;
float tpfittime;
float time_difference;
int i = 0;
int num_changes_per_loop = 1;
int counter = 0;
int j;
int currifitpk = 0;
int tmpcount = 0;
int tsize, gsize;
// vectors that need to be created that will hold everything
const int GBT_COORDINATE_LENGTH = 9;
std::vector<int> gbtmmfes = {};
std::vector<int> gbtvmms = {};
std::vector<int> gbtchs = {};
std::vector<int> gbtbcids = {};
std::vector<int> tpmmfes ={};
std::vector<int> tpvmms = {};
std::vector<int> tpchs = {};
std::vector<int> tpbcids = {};
// this vector will store the hit information for each track
// use i to compare to the gbt data
std::vector<int> tp_tmp_hit_storage = {};
std::vector<int> gbt_tmp_hit_storage = {};
int boards[] = {118,116,102,119,106,107,117,105};
//loop through the GBT set
tpfit_tree->Print();
i = 0;
while(gbt_tree->GetEntry(i))
{
gbtmmfes.clear();
gbtvmms.clear();
gbtchs.clear();
gbtbcids.clear();
// get the exact tiem of the event in nanoseconds by adding the time
// in seconds to the time in nanoseconds
gbttime = gbtTime_sec + gbtTime_nsec/pow(10.,9);
// if the time exceeds a certain limit, break
// eventually when we're out of the testing phase we'll remove the i limitation
if(i >=1000 || gbttime > 1495040000) { std::cout << "done" << std::endl;break; }
/* creating a list containing the coordinates for each part of the event*/
for(counter = 0; counter < 10; counter++)
{
try {gbtmmfes.push_back(gbtMMFE8->at(counter));}
catch (std::out_of_range& e) { break;}
// gbtmmfes.push_back(gbtMMFE8->at(counter));
gbtvmms.push_back(gbt_VMM->at(counter));
gbtchs.push_back(gbt_CH->at(counter));
gbtbcids.push_back(gbt_BCID->at(counter));
//std::cout << gbt_BCID->at(counter) << std::endl;
}
counter = 0;
//std::cout << gbtbcids.size() << std::endl;
// sort all the arrays by size
// this bit of code is a bubblesort, and it also sorts the other arrays
// by the same rule as the mmfe8 so that they remain aligned
while(counter++<GBT_COORDINATE_LENGTH)
{
if(num_changes_per_loop==0) { break; }
for(int counter1=0;counter1<gbtmmfes.size();counter1++)
{
int current_value = gbtmmfes[counter1];
int adjacent_value = gbtmmfes[counter1+1];
if(adjacent_value > current_value) {;}
else if(current_value > adjacent_value) {
int tmp = adjacent_value;
std::swap(gbtmmfes[counter1], gbtmmfes[counter1+1]);
std::swap(gbtvmms[counter1], gbtvmms[counter1+1]);
std::swap(gbtchs[counter1], gbtchs[counter1+1]);
std::swap(gbtbcids[counter1], gbtbcids[counter1+1]);
num_changes_per_loop++;
}
}
}
// check to see if there are any boards that did not fire, if thats the case
// replace their values with zeros by adding a new "event" to the array
for(counter=0; counter<7; counter++)
{
int *tmpaddress = std::find(std::begin(boards),std::end(boards), boards[counter]);
if( tmpaddress==std::end(boards) )
{
gbtmmfes.push_back(boards[counter]);
gbtvmms.push_back(0);
gbtchs.push_back(0);
gbtbcids.push_back(0);
std::cout << "Padded" << std::endl;
}
}
// for(int k=0; k<gbtbcids.size(); k++)
// {
// std::cout << gbtbcids[k] << std::endl;
// }
j = currifitpk;
while(TRUE) {
//get trigger process across #j, whatever j happens to be
int nmatch = 0;
tpfit_tree->GetEntry(j);
tpmmfes.clear();
tpvmms.clear();
tpchs.clear();
tpbcids.clear();
// if j is greater than the number of things in the fit tp file, break the loop
if( j == nfit ) { break; }
// start declaring all the track information from tpfittree
nevent = EventNum;
tpfittime = tpTime_sec + tpTime_nsec/pow(10.,9);
bcid = BCID;
mxloc = mxlocal;
nhit = tpfit_n;
spec_cntr = cntr;
for(counter = 0; counter < 10; counter++)
{
try {tpmmfes.push_back(tpfit_MMFE8->at(counter));}
catch (std::out_of_range& e) { break;}
tpmmfes.push_back(tpfit_MMFE8->at(counter));
tpvmms.push_back(tpfit_VMM->at(counter));
tpchs.push_back(tpfit_CH->at(counter));
}
// check the time difference betwen the tp and gbt packet
// they should ideally be very close together, some difference is acceptable
// but if the difference is greater than 0.2 we are misaligning the data
time_difference = tpfittime - gbttime;;
// break if we've gone to far
if( time_difference>0.2 ) { break; }
// if the time difference between the tp packet and the gbt packet
// is within reasonable error, do the following
time_difference = abs(time_difference);
if( time_difference<0.2 )
{
// std::cout << "yay" << std::endl;
// is the time of the tpfit packet in the list of the gbt packet BCIDS
// we created earlier? if so, continue
if( std::find(gbtbcids.begin(), gbtbcids.end(), bcid) != gbtbcids.end() )
{
std::cout << "The value " << bcid << " was found in the GBT packet" << std::endl;
// fill a vector with the single hit information to compare to the gbt stuff
for(int counter1=0; counter1<gbtmmfes.size(); counter1++)
{
gbt_tmp_hit_storage.clear();
gbt_tmp_hit_storage.push_back(gbtmmfes[counter1]);
gbt_tmp_hit_storage.push_back(gbtvmms[counter1]);
gbt_tmp_hit_storage.push_back(gbtchs[counter1]);
gsize = gbt_tmp_hit_storage.size();
//std::cout << "gsize " << gsize << std::endl;
for(int counter2=0; counter2<tpmmfes.size(); counter2++)
{
tp_tmp_hit_storage.clear();
tp_tmp_hit_storage.push_back(tpmmfes[counter2]);
tp_tmp_hit_storage.push_back(tpvmms[counter2]);
tp_tmp_hit_storage.push_back(tpchs[counter2]);
gsize = gbt_tmp_hit_storage.size();
tsize = tp_tmp_hit_storage.size();
//std::cout << "gsize and tsize " << gsize << " " << tsize << std::endl;
// are the coordinates int eh gbt set the same as the
// coordinates recorded by the trigger process? if yes
// continue, if no, don't do anything
if( gbt_tmp_hit_storage == tp_tmp_hit_storage )
{
// increment nmatch too add to the lsit of entries
// that have corresponding trigger events
nmatch += 1;
t_tpfit_MMFE8->push_back(tpmmfes[counter2]);
t_tpfit_VMM->push_back(tpvmms[counter2]);
t_tpfit_CH->push_back(tpchs[counter2]);
t_tpfit_BCID->push_back(gbtbcids[counter1]);
tmpcount = counter1;
}
}
}
// update the combined branches with all the new data
t_mxlocal = mxloc;
t_bcid = gbtbcids[tmpcount];
t_tpfit_n = nhit;
t_cntr = spec_cntr;
t_eventnum = nevent;
t_timesec = tpTime_sec;
t_timensec = tpTime_nsec;
std::cout << nmatch << " " << nhit << std::endl;
if( nmatch == nhit )
{
currifitpk = j + 1;
gDebug=1;
combdata->Fill();
std::cout << "FILLED FILLED FILLED" << std::endl;
}
t_tpfit_MMFE8->clear();
t_tpfit_VMM->clear();
t_tpfit_CH->clear();
t_tpfit_BCID->clear();
}
}
j++;
}
i++;
}
// // this is a test print funciton, im going to leave it for now
// // for(int counter = 0; counter < GBT_COORDINATE_LENGTH; counter++)
// // {
// // std::cout << gbtmmfes[counter] << std::endl;
// // }
// j++;
// }
output_file->Write();
output_file->Close();
return 0;
}
And the error, including the output of gDebug:
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007f174b78e4ca in __GI___waitpid (pid=12434, stat_loc=stat_loc
entry=0x7fff94d53380, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
#1 0x00007f174b707fbb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2 0x00007f174cb02064 in TUnixSystem::StackTrace() () from /home/vhx/Documents/root/lib/libCore.so
#3 0x00007f174cb046cc in TUnixSystem::DispatchSignals(ESignals) () from /home/vhx/Documents/root/lib/libCore.so
#4 <signal handler called>
#5 0x00007f174c486f40 in TBufferFile::WriteFastArray(int const*, int) () from /home/vhx/Documents/root/lib/libRIO.so
#6 0x00007f174c0d990c in TBranch::FillLeavesImpl(TBuffer&) () from /home/vhx/Documents/root/lib/libTree.so
#7 0x00007f174c0dcd8a in TBranch::Fill() () from /home/vhx/Documents/root/lib/libTree.so
#8 0x00007f174c10bf09 in TTree::Fill() () from /home/vhx/Documents/root/lib/libTree.so
#9 0x0000000000405126 in main (argc=4, argv=0x7fff94d56328) at combineTPGBT_standalone.c:345
===========================================================
The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum.
Only if you are really convinced it is a bug in ROOT then please submit a
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 0x00007f174c486f40 in TBufferFile::WriteFastArray(int const*, int) () from /home/vhx/Documents/root/lib/libRIO.so
#6 0x00007f174c0d990c in TBranch::FillLeavesImpl(TBuffer&) () from /home/vhx/Documents/root/lib/libTree.so
#7 0x00007f174c0dcd8a in TBranch::Fill() () from /home/vhx/Documents/root/lib/libTree.so
#8 0x00007f174c10bf09 in TTree::Fill() () from /home/vhx/Documents/root/lib/libTree.so
#9 0x0000000000405126 in main (argc=4, argv=0x7fff94d56328) at combineTPGBT_standalone.c:345
===========================================================
Info in <TFile::WriteStreamerInfo>: called for file combinedtest.root
TKey Writing 85 bytes at address 230 for ID= StreamerInfo Title= Doubly linked list
TKey Writing 55 bytes at address 315 for ID= combinedtest.root Title=
TKey Writing 61 bytes at address 370 for ID= combinedtest.root Title=
Info in <TFile::~TFile>: dtor called for datafiles/Run3522_GBT_decoded.root [24dcba0]
Info in <TDirectoryFile::~TDirectoryFile>: dtor called for datafiles/Run3522_GBT_decoded.root
Info in <TDirectory::~TDirectory>: dtor called for datafiles/Run3522_GBT_decoded.root
Info in <TFile::~TFile>: dtor called for datafiles/Run3522_FIT_decoded.root [3b01f90]
Info in <TDirectoryFile::~TDirectoryFile>: dtor called for datafiles/Run3522_FIT_decoded.root
Info in <TDirectory::~TDirectory>: dtor called for datafiles/Run3522_FIT_decoded.root
Info in <TFile::~TFile>: dtor called for combinedtest.root [3af9790]
Info in <TDirectoryFile::~TDirectoryFile>: dtor called for combinedtest.root
Info in <TDirectory::~TDirectory>: dtor called for combinedtest.root