Segmentation fault when looping over macro

I have a macro mini.C created using MakeClass() that contains the function Loop, which simply fills a histogram with the transverse momentum (lep_pt) for the selected .root file, then writes out the result to another .root file. I am using ATLAS OpenData, in which all the ROOT trees are named “mini”.

Now, I made a second script to loop over some of the different analysis files. Since the header files are different for data/MC in a way I can’t seem to reconcile, I initially copy the contents of the relevant header file into the file mini.h.

The loop is over a vector index of names of decay chains:

// i is the number of entries in the vector
for( int j=0; j<i; j++)
    {
      // Copy the relevant header file into mini.h 
      gSystem->Exec(TString::Format("cat %s.h > mini.h", names[j].c_str()));
      // Run the macro in ROOT
      gROOT->ProcessLine(".L mini.C+");
      gROOT->ProcessLine("mini t");
      gROOT->ProcessLine(TString::Format("t.Loop(\"%s\")",names[j].c_str()));

This executes the analysis code fine once, however upon the second running for a different decay chain I get a similar stack trace to that of the one below.

Now, I have added a gROOT->Reset() at the end of the Loop function, but this does not seem to resolve the problem as I may have expected. It seems to run twice now, but not three times, which is very eerie! The stack trace for this analysis is the stack trace I have copied into this post, which I don’t really understand.

Any help would be greatly appreciated! The end goal is to superpose the resulting histograms from multiple .root files on to the same TCanvas.

>  *** Break *** segmentation violation



> ===========================================================
> There was a crash.
> This is the entire stack trace of all threads:
> ===========================================================
> 0  0x000000324eeac82e in waitpid () from /lib64/libc.so.6
> 1  0x000000324ee3e479 in do_system () from /lib64/libc.so.6
> 2  0x00007fc629d24c5a 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  0x00007fc629d26c2c 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  0x00007fc61cfeb837 in mini::Loop(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from /afs/hep.man.ac.uk/u/eurioya/Software/mini_C.so
> 6  0x00007fc61f560080 in __cling_Un1Qu318(void*) ()
> 7  0x00007fc627206be8 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 8  0x00007fc62720ce69 in cling::Interpreter::EvaluateInternal(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 9  0x00007fc62720d035 in cling::Interpreter::process(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 10 0x00007fc6272b127b in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 11 0x00007fc6271b68ad in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 12 0x00007fc629c2e8b6 in TApplication::ProcessLine(char const*, bool, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 13 0x00007fc629ba5c11 in TROOT::ProcessLine(char const*, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 14 0x00007fc61f5721c2 in runmini(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
> 15 0x00007fc61f564076 in __cling_Un1Qu316(void*) ()
> 16 0x00007fc627206be8 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 17 0x00007fc62720ce69 in cling::Interpreter::EvaluateInternal(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 18 0x00007fc62720d08f in cling::Interpreter::echo(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 19 0x00007fc6272b75f9 in cling::MetaSema::actOnxCommand(llvm::StringRef, llvm::StringRef, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 20 0x00007fc6272c3479 in cling::MetaParser::isXCommand(cling::MetaSema::ActionResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 21 0x00007fc6272c450e in cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 22 0x00007fc6272b11b3 in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 23 0x00007fc6271b6cb9 in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 24 0x00007fc627191af7 in TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 25 0x00007fc629c2dcdd in TApplication::ExecuteFile(char const*, int*, bool) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 26 0x00007fc629c2ec9e in TApplication::ProcessLine(char const*, bool, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 27 0x00007fc629ba5c11 in TROOT::ProcessLine(char const*, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 28 0x00007fc61ec80eb6 in DivAn2() () from /afs/hep.man.ac.uk/u/eurioya/Software/DivAn2_C.so
> 29 0x00007fc629736042 in __cling_Un1Qu30(void*) ()
> 30 0x00007fc627206be8 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 31 0x00007fc62720ce69 in cling::Interpreter::EvaluateInternal(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 32 0x00007fc62720d035 in cling::Interpreter::process(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 33 0x00007fc6272b127b in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 34 0x00007fc6271b6e0d in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 35 0x00007fc627191af7 in TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 36 0x00007fc629c2dcdd in TApplication::ExecuteFile(char const*, int*, bool) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 37 0x00007fc629c2ec9e in TApplication::ProcessLine(char const*, bool, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 38 0x00007fc62a08ded5 in TRint::ProcessLineNr(char const*, char const*, int*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRint.so
> 39 0x00007fc62a08e101 in TRint::HandleTermInput() () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRint.so
> 40 0x00007fc629d263bd in TUnixSystem::CheckDescriptors() () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 41 0x00007fc629d274ca in TUnixSystem::DispatchOneEvent(bool) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 42 0x00007fc629c6c794 in TSystem::InnerLoop() () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 43 0x00007fc629c6ad81 in TSystem::Run() () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 44 0x00007fc629c2c0df in TApplication::Run(bool) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCore.so
> 45 0x00007fc62a08f55b in TRint::Run(bool) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libRint.so
> 46 0x0000000000401340 in main ()
> ===========================================================


> 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  0x00007fc61cfeb837 in mini::Loop(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from /afs/hep.man.ac.uk/u/eurioya/Software/mini_C.so
> 6  0x00007fc61f560080 in __cling_Un1Qu318(void*) ()
> 7  0x00007fc627206be8 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 8  0x00007fc62720ce69 in cling::Interpreter::EvaluateInternal(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 9  0x00007fc62720d035 in cling::Interpreter::process(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> 10 0x00007fc6272b127b in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/root/6.04.14-x86_64-slc6-gcc49-opt/lib/libCling.so
> ===========================================================

It looks like your macro mini.C is not re-entrant some how.

Also I find the line…

      gROOT->ProcessLine("mini t");
``

...a bit strange ... `ProcessLine` is supposed to execute a ROOT command.  I wondered what `mini t` could be ?  if the previous `.L`  loaded a function called `mini`  then the command should be `mini(t)`... may be I missed something ...
1 Like

As far as I am aware, this is a pretty standard way to make an object of type “filename” and run a macro is it not?

Also, do you have any idea on how I may resolve that? :stuck_out_tongue:

Ah ok … in your macro you have a class “mini” ?

In the header file yes, in the standard way with MakeClass(“mini”) :slight_smile:
http://atlas.fis.utfsm.cl/atlas/tutorial.root.utfsm.html#MakeClass

I don’t like your approach at all. Just to loop over a different dataset, you want to copy a header file, recompile, and execute again? Sounds really not like the way to go.

I don’t really understand why you need to do it this way. Can’t you just have a class miniMC and miniData?
Just make a function that returns the histogram. Don’t know how many different .h files you have - and how much different are they? Is the difference important? If you just want to draw lep_pt, you could simply do tree->Draw("lep_pt").

You should really reconsider your approach and get rid of the gSystem->Exec and gROOT->ProcessLine calls.

2 Likes

So we are back to my first remark, that your code is not re-entrant … May be you create objects which are not deleted and therefore redefined when you execute the 2nd times ? I do not think gROOT->Reset() will help with that.

Yes I know it’s not ideal, it’s the only thing we thought of at the time!

So the only thing that’s different besides the file name being imported is the size of the arrays of the defined variables. Classes miniMC and miniData may work actually – how would that work for differing filename imports within a class?

We thought of this too – can’t seem to find anything made on the heap that isn’t deleted!

Reentrancy is a different topic, this code is not called again in the middle of its execution.

I have never seen such a weird setup :stuck_out_tongue: I don’t know what exactly makes the execution crash, but I would also suggest to move to a more solid approach.

In the end you just want to loop on three different files with three different classes…? Why can’t you just have three different headers and three different mini objects? Something like

#include "mini1.h"
#include "mini2.h"
#include "mini3.h"
int main() {
  mini1 t1;
  t1.Loop("filename1");
  mini2 t2;
  t2.Loop("filename2");
  min3 t3;
  t3.Loop("filename3");
  return 0;
}

If for some reason you really have to run the loop with three different mini.h files, you can have a macro that does something like the following

 gROOT->ProcessLine(".L mini.C+");
 gROOT->ProcessLine("mini t");
 gROOT->ProcessLine(TString::Format("t.Loop(\"%s\")",argv[1]));

and a bash script that calls it with the appropriate argument after changing the mini.h file.
Note that this is very inefficient.

P.S.
the crash is likely due to the fact that you end up with multiple definitions for the mini class and multiple definitions of the t variable as well in memory.

1 Like

Hi,

Thanks for this response – the reason why I was doing it this way is that Loop is a member of class mini, so surely if I import three differently named headers I would need three corresponding Loop functions, which is the main thing we’re trying to avoid.

Do you know how I could do this without 3 functions? I was thinking just making it a friend of every class.

uhm, I am not sure I understand…different classes (mini1, mini2, mini3) can have a method with the same name.

Yes, but surely you would need to seperately define mini1::Loop(), mini2::Loop() and mini3::Loop()? The goal here is just to have one definition.

If just the array size if different, can’t you simply take the larger one?

Also the filename imported as a TFile is different – making different classes will force me to make more than one
function that does exactly the same thing – how would I get around this?

I would follow @behrenhoff 's line of thought.

What you are doing (using the same definition (.C) for several slightly different declarations (.h) of the same class, in the same program) is not something that any programming language I know of is designed to support.
I think your best bet is either

  • script (using a scripting language like bash or python, not c++!) the switching of source files and compile a separate executable with each version of your mini class (inefficient, awkward)
  • write one single general mini class that supports all the slightly different behaviours that you now have in your several different header files: for example, make the size of the array a parameter of the class constructor, as well as the filename of the TFile

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