TH1::LabelsOption - segmentation fault

Hi ROOTers,

I try to fill a histogram from a tree and want to use bin labels. When I try to sort them using TH1::LabelsOption after filling I get a segmentation fault. Same thing when I choose the option in the browser. I use ROOT 5.28-00c. I’d appreciate any advise on what to change in my script…Thanks!

Daniel

#include "TTree.h"
#include "TFile.h"
#include "TH1.h"
#include "TH2.h"
#include "TCanvas.h"
#include "TProfile.h"
#include <iostream>

void test( const char* file_name  // state population tree file
           ) {
   //
   //
   //
   TFile file( file_name, "READ");
   TTree* tree = (TTree*)file.Get("tree");
   
   int state(0);
   int lmdoutnogl(0);
   char casestr[256] = {""};
   float phase(0.0);

   tree->SetBranchAddress("state", &state);
   tree->SetBranchAddress("lmdoutnogl", &lmdoutnogl);
   tree->SetBranchAddress("case", casestr);
   tree->SetBranchAddress("phase", &phase);
   
   tree->SetBranchStatus("*",0);
   tree->SetBranchStatus("state",1);
   tree->SetBranchStatus("lmdoutnogl",1);
   tree->SetBranchStatus("case",1);
   tree->SetBranchStatus("phase",1);
   
   int nBins = tree->GetMaximum("lmdoutnogl");
   
   TH2F h("h","State population vs. beam delivery sequence (phase=0 deg.)",nBins,-0.5,nBins+0.5,22,-0.5,21.5);
   
   for ( int iEntry = 0; iEntry < 10; ++iEntry ) {
      tree->GetEntry(iEntry);
      if ( phase == 0 ) {
         h.Fill(casestr, state, 1);
      }
   }
   
   TCanvas* c = new TCanvas("c", "State population vs. beam delivery sequence (phase=0 deg.)", 1280, 600);
   c->SetLeftMargin(0.05);
   c->SetBottomMargin(0.25);
   
   h.GetXaxis()->SetRangeUser(0,nBins);
   h.LabelsOption("a","X");
   h.DrawCopy("COLZ");
   
   file.Close();
}

Has nobody encountered the same problem?

can you provide the file containing the tree you are using in this macro ?

Hi,

I attached a ROOT file with a tree containing a subset of the entries of the tree I was using. It would be great if you could have a look if you have the same problem.

Best,
Daniel
test.root (466 KB)

The following id fine for me:

{
   TFile *file = new TFile( "test.root", "READ");
   TTree* tree = (TTree*)file.Get("tree");

   int state(0);
   int lmdoutnogl(0);
   char casestr[256] = {""};
   float phase(0.0);

   tree->SetBranchAddress("state", &state);
   tree->SetBranchAddress("lmdoutnogl", &lmdoutnogl);
   tree->SetBranchAddress("case", casestr);
   tree->SetBranchAddress("phase", &phase);

   tree->SetBranchStatus("*",0);
   tree->SetBranchStatus("state",1);
   tree->SetBranchStatus("lmdoutnogl",1);
   tree->SetBranchStatus("case",1);
   tree->SetBranchStatus("phase",1);

   int nBins = tree->GetMaximum("lmdoutnogl");

   TH2F *h = new TH2F("h","State population vs. beam delivery sequence (phase=0 deg.)",nBins,-0.5,nBins+0.5,22,-0.5,21.5);

   for ( int iEntry = 0; iEntry < 10; ++iEntry ) {
      tree->GetEntry(iEntry);
      if ( phase == 0 ) {
         h->Fill(casestr, state, 1);
      }
   }

   TCanvas* c = new TCanvas("c", "State population vs. beam delivery sequence (phase=0 deg.)", 1280, 600);
   c->SetLeftMargin(0.05);
   c->SetBottomMargin(0.25);

   h->GetXaxis()->SetRangeUser(0,nBins);
   h->LabelsOption("a","X");
   h->DrawCopy("COLZ");

   file->Close();
}

It seems to me that the problem is related to:
TH2F h(…); // original source code -> “segmentation violation” guaranteed
versus:
TH2F *h = new TH2F(…); // Olivier’s source code -> no "segmentation violation"
It this a “feature” or a “bug”?
The simplest way to demonstrate it is:

[code]root [0] TFile file(“test.root”, “READ”);
root [1] TH2F h(“h”, “h”, 1, 0, 1, 1, 0, 1);
root [2] file.Close();
root [3] .q

*** Break *** segmentation violation

===========================================================
There was a crash (#7 0xb71b15ed in SigHandler(ESignals) ()).
This is the entire stack trace of all threads:

#0 0xb76ed430 in __kernel_vsyscall ()
#1 0xb67507d3 in __waitpid_nocancel ()
at …/sysdeps/unix/syscall-template.S:82
#2 0xb66f1de3 in do_system (line=)
at …/sysdeps/posix/system.c:149
#3 0xb682127d in system (
line=0x97f1c30 “/…/root/etc/gdb-backtrace.sh 3652 1>&2”) at pt-system.c:29
#4 0xb71ab58d in TUnixSystem::Exec(char const*) ()
from /…/root/lib/libCore.so.5.33
#5 0xb71b2d76 in TUnixSystem::StackTrace() ()
from /…/root/lib/libCore.so.5.33
#6 0xb71b14df in TUnixSystem::DispatchSignals(ESignals) ()
from /…/root/lib/libCore.so.5.33
#7 0xb71b15ed in SigHandler(ESignals) ()
from /…/root/lib/libCore.so.5.33
#8 0xb71a83a2 in sighandler(int) ()
from /…/root/lib/libCore.so.5.33
#9 0xb71d810d in textinput::TerminalConfigUnix::HandleSignal(int) ()
from /…/root/lib/libCore.so.5.33
#10 0xb71d84e6 in (anonymous namespace)::TerminalConfigUnix__handleSignal(int)
() from /…/root/lib/libCore.so.5.33
#11
#12 0x09d4b380 in ?? ()
#13 0xb6a01da7 in Cint::G__ExceptionWrapper(int ()(G__value, char const*, G__param*, int), G__value*, char*, G__param*, int) ()
from /…/root/lib/libCint.so.5.33
#14 0xb6ab18ff in G__execute_call ()
from /…/root/lib/libCint.so.5.33
#15 0xb6ab27aa in G__call_cppfunc ()
from /…/root/lib/libCint.so.5.33
#16 0xb6a8c43b in G__interpret_func ()
from /…/root/lib/libCint.so.5.33
#17 0xb6a7a0fd in G__getfunction ()
from /…/root/lib/libCint.so.5.33
#18 0xb6b30b91 in G__destroy_upto ()
from /…/root/lib/libCint.so.5.33
#19 0xb6b30cdc in G__scratch_globals_upto ()
from /…/root/lib/libCint.so.5.33
#20 0xb7167569 in TCint::ResetGlobals() ()
from /…/root/lib/libCore.so.5.33
#21 0xb71ab532 in TUnixSystem::Exit(int, bool) ()
from /…/root/lib/libCore.so.5.33
#22 0xb70a6584 in TApplication::Terminate(int) ()
from /…/root/lib/libCore.so.5.33
#23 0xb699b38e in TRint::Terminate(int) ()
from /…/root/lib/libRint.so.5.33
#24 0xb70a8213 in TApplication::ProcessLine(char const*, bool, int*) ()
from /…/root/lib/libCore.so.5.33
#25 0xb699cc05 in TRint::HandleTermInput() ()
from /…/root/lib/libRint.so.5.33
#26 0xb699b055 in TTermInputHandler::Notify() ()
from /…/root/lib/libRint.so.5.33
#27 0xb699e2c4 in TTermInputHandler::ReadNotify() ()
from /…/root/lib/libRint.so.5.33
#28 0xb71af397 in TUnixSystem::CheckDescriptors() ()
from /…/root/lib/libCore.so.5.33
#29 0xb71af568 in TUnixSystem::DispatchOneEvent(bool) ()
from /…/root/lib/libCore.so.5.33
#30 0xb7116924 in TSystem::InnerLoop() ()
from /…/root/lib/libCore.so.5.33
#31 0xb71199e9 in TSystem::Run() ()
from /…/root/lib/libCore.so.5.33
#32 0xb70a6277 in TApplication::Run(bool) ()
from /…/root/lib/libCore.so.5.33
#33 0xb699dabb in TRint::Run(bool) ()
from /…/root/lib/libRint.so.5.33
#34 0x08048ecf 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.

#12 0x09d4b380 in ?? ()

Root > .qqq[/code]
BTW. I think it makes sense to make sure that “nBins” is “positive”:
int nBins = tree->GetMaximum(“lmdoutnogl”);
if (nBins < 1) nBins = 1;

Hi Olivier

thanks for testing. You are right, your code also works for me. However, I apparantly did not pick such a good subset of my tree (its several hundred MB in total). So there was just only one unique string in the “case” tree branch and this seems to make the difference because then I only get a histogram with one bin only. I realized that when I fill the histograms with

using the full tree, apart from labeled bins I also get a number of empty bins without labels. I do not really understand why, as there should always be a non-empty string in the “case” variable. Whatever, If I then try to sort the labels after filling I get the crash (@Pepe, it’s definetely not the constructor. But I agree, the code is anything but safe…). Now, if I call TH1::LabelsDeflate before doing the sort everything seems to be fine. So it looks as if the empty labels are what causes the crash. And it really seems to be a sorting thing because the LabelOptions only manipulating the orientation of the labels do not cause a crash.

Best,
Daniel

May be you should provide a subset reproducing the problem ?

Hi Olivier,

sorry, I needed a while to respond. I prepared a new ROOT file + tree and a small example code which for me results into a seg fault using LabelsOption() without calling LabelsDeflate before. Please have a try with this code snippet and the attached ROOT file.

{
   TFile f("example.root", "READ");
   TTree* tree = (TTree*)gDirectory->Get("tree");
   
   char casestr[256] = {""};
   tree->SetBranchAddress("case", casestr);

   TH2F h("h", "", 92, -0.5, 91.5, 21, -0.5, 21.5);

   for ( long iEntry = 0; iEntry < tree->GetEntries(); ++iEntry ) {
      tree->GetEntry(iEntry);
      h.Fill(casestr,5,1);
   }

   h.Draw("COLZ");
   //h.LabelsDeflate();
   h.LabelsOption("a");
  
}

example.root (118 KB)

Hi,

This problem is due to a bug which is now fixed in the current trunk and 5.32 patches.
Thank you for your report

Lorenzo

Ok,

great! That’s what I figured…

best
Daniel