Segmentation violation when running, not when pasted

Hi, I am having trouble understanding why my code crashes when I execute a function. If I just paste the function body into cling it seems to run fine.

My code: (note, I removed irrelevant separate functions for pasting here, but I couldn’t see any line numbers or references to my code in the backtrace, hopefully it is ok)

#include "Likelihood.C"
#include "Geom.C"
#include "TRandom3.h"
#include "TMultiGraph.h"
#include "TH2.h"
#include "TPaletteAxis.h"
#include <vector>
TMultiGraph * test2()
{ // Initialize some stuff.
  Likelihood::LikelihoodInfo lhi("cluster_info_00500_60.root");
  const Geom::Side theside = Geom::BOTH;
  const int n_slices = lhi.ranges.at(theside)->GetNoElements();
  const int n_graphs = 10;
  TRandom3 tr3(1234);
  TMultiGraph * mg = new TMultiGraph("test2_mg","test2_mg");

  // Make the TGraphs and keep track of n_clu.
  int n_clu_min = std::numeric_limits<int>::max();
  int n_clu_max = 0;
  std::vector<TGraph *> graphs;
  std::vector<int> n_clus;
  for(int i = 0; i < n_graphs; i++){
    const int n_clu = tr3.Poisson(7);
    const int n_slice = tr3.Integer(n_slices);
    const TH1D * const h = static_cast<TH1D*>(lhi.toas.at(theside)->At(n_slice));
    std::vector<int> clusters;
    for(int j = 0; j < n_clu; j++){
      clusters.push_back(h->GetRandom());
    }
    TGraph * g = lhi.graph_nll2(clusters,theside);
    graphs.push_back(g);
    n_clus.push_back(n_clu);
    mg->Add(g);
    if(n_clu < n_clu_min) n_clu_min = n_clu;
    if(n_clu > n_clu_max) n_clu_max = n_clu;
  }

  // Make a junk TH2 so I can use its TPaletteAxis object.
  TH2D h2("junk","junk",10,0,10,10,0,10);
  h2.Fill(5,5);
  h2.SetMaximum(n_clu_max+1);
  h2.SetMinimum(n_clu_min);
  h2.Draw("colz");
  TPaletteAxis *palette = static_cast<TPaletteAxis*>(h2.GetListOfFunctions()->FindObject("palette"));

  // Color the TGraph lines according to the n_clu parameter for each TGraph.
  for(int i = 0;i < n_graphs;i++){
   int c = palette->GetValueColor(n_clus[i]);
   graphs[i]->SetLineColor(c);
  }

  return mg;
}

Here is what happens when I try to .L it and run the function:

*  ROOT v6.03/01  *

root [0] .L test_nll.C+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/jfcaron/Projects/Proto2BeamTest2/./test_nll_C.so
root [1] TMultiGraph * mg = test2()
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1

 *** Break *** segmentation violation
 Generating stack trace...
 0x000000010fa81ceb in (anonymous namespace)::TerminalConfigUnix__handleSignal(int) (in libCore.so) (TerminalConfigUnix.cpp:37)
 0x00007fff8d04f5aa in _sigtramp (in libsystem_platform.dylib) + 26
 0x00007f922c413b00 in <unknown function>
 0x000000011e3b91fe in test2() (in test_nll_C.so) + 3486
 0x0000000112b1a960 in <unknown function>
 0x0000000112b1a940 in <unknown function>
 0x00000001112c113d in llvm::JIT::runFunction(llvm::Function*, std::__1::vector<llvm::GenericValue, std::__1::allocator<llvm::GenericValue> > const&) (in libCling.so) + 2637
 0x000000011038774f in cling::IncrementalExecutor::runStaticInitializersOnce(llvm::Module*) (in libCling.so) (IncrementalExecutor.cpp:332)
 0x00000001103a8a39 in cling::Interpreter::runStaticInitializersOnce(cling::Transaction const&) const (in libCling.so) (Interpreter.cpp:1156)
 0x0000000110391e59 in cling::IncrementalParser::commitTransaction(cling::Transaction*) (in libCling.so) (IncrementalParser.cpp:424)
 0x0000000110392ede in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) (in libCling.so) (IncrementalParser.cpp:696)
 0x00000001103a7acb in cling::Interpreter::EvaluateInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::CompilationOptions const&, cling::Value*, cling::Transaction**
 0x00000001103a678a in cling::Interpreter::process(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::Value*, cling::Transaction**) (in libCling.so) (Interpreter.cpp:504)
 0x0000000110450a37 in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) (in libCling.so) (MetaProcessor.cpp:162)
 0x000000010ffe499f in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (in libCling.so) (TCling.cxx:1870)
 0x000000010f85216c in TApplication::ProcessLine(char const*, bool, int*) (in libCore.so) (TApplication.cxx:982)
 0x000000010fe7cf0d in TRint::ProcessLineNr(char const*, char const*, int*) (in libRint.so) (TRint.cxx:727)
 0x000000010fe7ef75 in TRint::HandleTermInput() (in libRint.so) (TRint.cxx:599)
 0x000000010fe7a8ca in TTermInputHandler::Notify() (in libRint.so) (TRint.cxx:124)
 0x000000010fe80709 in TTermInputHandler::ReadNotify() (in libRint.so) (TRint.cxx:116)
 0x000000010f9d01be in TUnixSystem::CheckDescriptors() (in libCore.so) (TUnixSystem.cxx:1297)
 0x000000010f9e0dac in TMacOSXSystem::DispatchOneEvent(bool) (in libCore.so) (TMacOSXSystem.mm:361)
 0x000000010f8e86a3 in TSystem::InnerLoop() (in libCore.so) (TSystem.cxx:410)
 0x000000010f8e84d3 in TSystem::Run() (in libCore.so) (TSystem.cxx:359)
 0x000000010f853e04 in TApplication::Run(bool) (in libCore.so) (TApplication.cxx:1131)
 0x000000010fe7cdbd in TRint::Run(bool) (in libRint.so) (TRint.cxx:453)
 0x000000010f73eb07 in main (in root.exe) (rmain.cxx:31)
 0x00007fff90a035fd in start (in libdyld.dylib) + 1
 0x0000000000000003 in <unknown function>
Root > .q

Also a blank canvas pops up during the crash, and I get more backtraces if I move the mouse over this canvas before quitting.

Additional files needed to .L the code are attached (and work fine outside of this example).

If I instead .L the dependent files and copy & paste the content of the function into cling, it works as expected. It creates a TMultiGraph with 10 TGraphs in it, each with a line color according to n_clu values in the loop.

It would be really nice to be able to read these backtraces, but they are really quite arcane. The errors we get when compiling by comparison are very useful. Is there any hope of improving the error messages from crashes to the level of the compilation error messages?

Thanks,
Jean-François
cluster_info_00500_60.root (836 KB)
Geom.C (11.1 KB)
Likelihood.C (27.8 KB)

Of course within minutes of posting the big question above, I manage to guess the right answer.

Adding #include “TPad.h” and doing

gPad->Modified();
gPad->Update();

after the h2.Draw call makes the crash go away. Turns out the *palette was a null pointer because the thing didn’t really get drawn so FindObject returned 0.

Jean-François