Segmentation fault in GetEntry()

Hello,

I have the following simple code just to test my data file.

[code]#include
#include
#include
#include <stdlib.h>
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include

#include “TROOT.h”
#include “TFile.h”
#include “TTree.h”
#include “TChain.h”
#include “TBranch.h”
#include “TFileCollection.h”
#include “TApplication.h”
#include “TChainElement.h”
#include “TObjArray.h”
#include

#if defined(MAKECINT) || defined(CINT)
#pragma link C++ class vector<vector >+;
#endif

using namespace std;
//using namespace Root;

int main(int argc, char **argv)
{

// TApplication App(argv[0],&argc,argv);
gROOT->ProcessLine("#include “);
const char* physics = “physics”;
TChain chain(physics,”");
const char * dataset = “”;
string datasetstg(argv[1]);
if (argc>1){
cout << " \tDatasets will be read from: " << (argv[1]) << endl;
dataset = (argv[1]);
}

ifstream myfile;
myfile.open( dataset, ios::in);
if (!myfile) {
cout << " Read Datasets: Can’t open input file: " << datasetstg << endl;
exit(1);
} else {
cout << “\n Read data file=” << dataset << “\n”<<endl;
}
string temp;
while (myfile >> temp) {
if (temp.find("#") != -1) continue;
//m_outfile = temp + “.root”;
//cout << temp << endl;
//temp = temp + “/physics”;
cout<<temp.c_str()<<endl;
chain.AddFile( temp.c_str() );
cout<<temp<<endl;
}

TObjArray *fileElements=chain.GetListOfFiles();
TIter next(fileElements);
TChainElement chEl=0;
while (( chEl=(TChainElement
)next() )) {
TFile f(chEl->GetTitle());
cout<<f.GetName()<<endl;
}

Int_t el_pt;
TBranch *b_el_pt;
chain.SetBranchAddress(“el_pt”, &el_pt, &b_el_pt);
try
{
// main loop
Long64_t nentries = chain.GetEntries();
cout<<“number of entries”<<nentries<<endl;
for (Long64_t jentry=0; jentry<nentries;jentry++)
{
Long64_t ientry = chain.LoadTree(jentry);
// cout<<“here”<<endl;
cout<<ientry<<endl;
// if (ientry < 0)
// break;

Int_t currentEntry =   chain.GetEntry(ientry);    

}
}
catch (exception& e)
{
cout << e.what() << endl;
}

}
[/code]

Everything works except when I come to chain.getEntry(ientry). From there I get segmentation fault with the following info:

[code] Datasets will be read from: input.txt

Read data file=input.txt

NTUP_SMWZ.742823._000005.root
NTUP_SMWZ.742823._000005.root
Warning in TClass::TClass: no dictionary for class AttributeListLayout is available
Warning in TClass::TClass: no dictionary for class pair<string,string> is available
NTUP_SMWZ.742823._000005.root
number of entries10000
0

*** Break *** segmentation violation

===========================================================
There was a crash (#6 0x00ab79db in SigHandler(ESignals) () from /home/user/root/lib/libCore.so).
This is the entire stack trace of all threads:

#0 0x008cd416 in __kernel_vsyscall ()
#1 0x0039e3e3 in waitpid () from /lib/i386-linux-gnu/libc.so.6
#2 0x0033e6e3 in ?? () from /lib/i386-linux-gnu/libc.so.6
#3 0x00ab08db in TUnixSystem::Exec(char const*) () from /home/user/root/lib/libCore.so
#4 0x00ab4dc0 in TUnixSystem::StackTrace() () from /home/user/root/lib/libCore.so
#5 0x00ab78c7 in TUnixSystem::DispatchSignals(ESignals) () from /home/user/root/lib/libCore.so
#6 0x00ab79db in SigHandler(ESignals) () from /home/user/root/lib/libCore.so
#7 0x00aaeb12 in sighandler(int) () from /home/user/root/lib/libCore.so
#8
#9 0x00526a21 in TBufferFile::ReadFastArray(float*, int) () from /home/user/root/lib/libRIO.so
#10 0x0055e45e in void TGenCollectionStreamer::ReadBufferVectorPrimitives(TBuffer&, void*) () from /home/user/root/lib/libRIO.so
#11 0x0055a833 in TGenCollectionStreamer::ReadBuffer(TBuffer&, void*) () from /home/user/root/lib/libRIO.so
#12 0x0052c538 in TCollectionClassStreamer::Stream(TBuffer&, void*, TClass const*) () from /home/user/root/lib/libRIO.so
#13 0x00a806d7 in TClass::StreamerExternal(void*, TBuffer&, TClass const*) const () from /home/user/root/lib/libCore.so
#14 0x005273c5 in TBufferFile::ReadFastArray(void*, TClass const*, int, TMemberStreamer*, TClass const*) () from /home/user/root/lib/libRIO.so
#15 0x005793f5 in int TStreamerInfoActions::ReadSTL<&TStreamerInfoActions::ReadSTLMemberWiseSameClass, &TStreamerInfoActions::ReadSTLObjectWiseFastArray>(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*) () from /home/user/root/lib/libRIO.so
#16 0x00526bc9 in TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*) () from /home/user/root/lib/libRIO.so
#17 0x07467204 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.

#9 0x00526a21 in TBufferFile::ReadFastArray(float*, int) () from /home/user/root/lib/libRIO.so
#10 0x0055e45e in void TGenCollectionStreamer::ReadBufferVectorPrimitives(TBuffer&, void*) () from /home/user/root/lib/libRIO.so
#11 0x0055a833 in TGenCollectionStreamer::ReadBuffer(TBuffer&, void*) () from /home/user/root/lib/libRIO.so
#12 0x0052c538 in TCollectionClassStreamer::Stream(TBuffer&, void*, TClass const*) () from /home/user/root/lib/libRIO.so
#13 0x00a806d7 in TClass::StreamerExternal(void*, TBuffer&, TClass const*) const () from /home/user/root/lib/libCore.so
#14 0x005273c5 in TBufferFile::ReadFastArray(void*, TClass const*, int, TMemberStreamer*, TClass const*) () from /home/user/root/lib/libRIO.so
#15 0x005793f5 in int TStreamerInfoActions::ReadSTL<&TStreamerInfoActions::ReadSTLMemberWiseSameClass, &TStreamerInfoActions::ReadSTLObjectWiseFastArray>(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*) () from /home/user/root/lib/libRIO.so
#16 0x00526bc9 in TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*) () from /home/user/root/lib/libRIO.so
#17 0x07467204 in ?? ()

[/code]

I have tried everything to make it work but run constantly into segmentation fault at the GetEntry line. Can anyone see what I doing wrong or if I am missing something? Grateful for any help…Thanks.
Donya.

Hi,

Most likely: Int_t el_pt; TBranch *b_el_pt; chain.SetBranchAddress("el_pt", &el_pt, &b_el_pt); the branch ‘el_pt’ contains a vector (and/or an array) rather than a single int. (See the result of chain.Print() for more details).

Cheers,
Philippe.

That’s an interesting issue.

Apparently, TChain::SetBranchAddress returns 5 (kNoCheck) if the requested branch does not exist at all (instead of -5 / kMissingBranch) and it happily returns 0 (kMatch) even in case of an object’s pointer type mismatch (instead of -2 / kMismatch). This happens in both, the interpreted code and the (ACLiC pre-)compiled code.

Note: the fact that “SetBranchAddress” (almost) always returns improper values (and no verbose error messages are printed on the screen) is actually a bug/problem in ROOT. It has been fixed in the ROOT “trunk” and in the “v5-34-00-patches” branch, in revision 46373, as of 2012-10-06.
Hint: In case you use a TChain, before you try to “MyChain->SetBranchAddress(…);”, you need to make sure that the tree has been loaded -> execute, for example, “MyChain->LoadTree(0);” -> otherwise the “TBranch::SetBranchAddress” will always return 5 (kNoCheck = underlying TBranch not yet available so no check was made).

Hi Will E.,

Could you take a look at why TChain::SetBranchAddress behaves differently and propose a patch fixing the behavior (if needed)?

Thanks,
Philippe.

Hi,

Thanks for your replies.Yes I realised later that I should change it from Int_t to a vector and finally after some more detective work got it to work and produced my results :slight_smile: .

It would be great though if SetBranchAddress could reply back with a more intuitive error which may hint towards the cause? Is that what the patch is about?

By the way, does ROOT contain its set of Exceptions to be tried and caught when writing classes?

cheers
Donya

Hi Donya,

[quote]It would be great though if SetBranchAddress could reply back with a more intuitive error which may hint towards the cause? Is that what the patch is about?[/quote]Well a step toward that direction, but not yet for your case.

[quote]By the way, does ROOT contain its set of Exceptions to be tried and caught when writing classes?[/quote]No, you should check the return values.

Cheers,
Philippe.

[quote=“pcanal”]

Well, are you saying now that, in this case, the SetBranchAddress will still happily return 0 without doing a proper check?

There’s something I’d already wanted to propose (but I forgot about it) …
Maybe you could introduce a new type of error in the CheckBranchAddressType → something like “kWTF (666) : We were unable to check the consistency of your request, sorry”.
And so, in all “suspicious” cases in which CheckBranchAddressType “happily” but “illegally” returns 0 now, it would return that new error, plus a verbose warning should be written on the screen.
It then would be on the user to “manually” check that everything is o.k. → but at least one would get a clear warning.

[quote]Maybe you could introduce a new type of error in the CheckBranchAddressType -> something like “kWTF (666) : We were unable to check the consistency of your request, sorry”.[/quote]Unfortunately, the likelihood that this would issue a warning in a perfectly legal case is high. On the other hand if you were to propose a patch that properly distinguish between the various cases that would be great.

Thanks,
Philippe.

[quote=“pcanal”]Unfortunately, the likelihood that this would issue a warning in a perfectly legal case is high.[/quote] Then maybe I would like to propose a “debug warning” instead of an “error”.
Something like … in any suspicious case … if (gDebug) print_a_verbose_message;

In my opinion, correct, robust, and well documented branch checking should be a high priority for the ROOT team: the IO libraries are central to every analysis, and improperly set branches account for a huge fraction of segfaults. I would like to see this resolved.

Hi,

As a side-note SetBranchAddress now returns an error code in case of issues and is a bit stricter about when it will use the user’s object’s address (i.e. in case of error, it no longer use the address).

Cheers,
Philippe.