TCanvas::SaveAs() segfaults when histogram titles contain latex

Hi all. I am having a problem where ROOT crashes when I try and save my TCanvas, provided that the histogram title uses any latex characters. This is especially strange for two reasons: it was working previously (I have tried running an old version of the code and found that it no longer works); and also my canvas is made up of two TPads, one for a TH1D and one for a TGraph, and the TGraph axis labels contain latex that draws just fine.

Some info: I have tried this both using ROOT 6.12/06 (on lxplus nodes) and 6.14/04 (on local machine, sourced from cvmfs).

Here is a pared-down version of the code for the function that is formatting & saving the figures:

void genProjectionHists_s::PlotProjection(TH1* hist_a, TH1* hist_b, const char* outputLocation, const char* figureTitle = "Title", const char* figureXLabel = "X-axis label") {
	// Sum weights
	hist_a->Sumw2();
	hist_b->Sumw2();
	
	// Scale histograms
	hist_a->Scale(1./hist_a->Integral());
	hist_b->Scale(1./hist_b->Integral());
	
	// Calculate residuals
	Double_t resVals[200];
	Double_t xVals[200];
	int numOfBins = hist_a->GetNbinsX();
	double Xmin = hist_a->GetXaxis()->GetXmin();
	double Xmax = hist_a->GetXaxis()->GetXmax();
	for (int i = 0; i < numOfBins; i++) {
		// calculate x position
		xVals[i] = Xmin + i*Xmax/numOfBins;
		// residuals: res[n] = (a[n] - b[n])/sqrt(err_a[n]^2 + err_b[n]^2)
		if (hist_a->GetBinContent(i+1) > 0 && hist_b->GetBinContent(i+1) > 0 && hist_a->GetBinError(i+1)+hist_b->GetBinError(i+1) > 0.) {
			resVals[i] = (hist_a->GetBinContent(i+1) - hist_b->GetBinContent(i+1))/sqrt(pow(hist_a->GetBinError(i+1),2) + pow(hist_b->GetBinError(i+1),2));
		}
	}
	
	// Create & format graph
	TGraph *gr = new TGraph(numOfBins, xVals, resVals);
	gr->SetTitle(""); // figure title goes to histogram, graph has no title
	gr->GetXaxis()->SetRangeUser(Xmin, Xmax);
	gr->GetXaxis()->SetTitle(figureXLabel);
	gr->GetXaxis()->SetTitleSize(.1);
	gr->GetXaxis()->SetLabelSize(.1);
	gr->GetYaxis()->SetTitle("Pulls");
	gr->GetYaxis()->SetTitleOffset(0.5);
	gr->GetYaxis()->SetTitleSize(.1);
	gr->GetYaxis()->SetLabelSize(.1);
	gr->SetFillColor(1);
	gr->SetMarkerStyle(21);
	
	// Format histograms
	hist_a->SetTitle(figureTitle);
	hist_a->GetXaxis()->SetLabelOffset(999);
	hist_a->GetXaxis()->SetLabelSize(0);
	hist_a->GetYaxis()->SetTitle("Events (normalised to 1)");
	hist_a->GetYaxis()->SetTitleOffset(1.4);
	hist_a->SetLineColor(kBlue);
	hist_b->SetLineColor(kRed);
	
	// Create canvas & pads
	TCanvas* canv = new TCanvas("canv", "", 1000, 1000);
	TPad *padh = new TPad("padh","",0.05,0.30,0.95,0.95,0); // histograms
	TPad *padr= new TPad("padr","",0.05,0.05,0.95,0.30,0); // residuals
	padh->SetBottomMargin(0.02);
	padr->SetTopMargin(0.);
	padr->SetBottomMargin(0.25);
	padr->SetTickx();
	padh->Draw();
	padr->Draw();
	
	// Draw to residuals pad
	padr->cd();
	gr->Draw("AB"); // draw residuals
	// Draw to histograms pad
	padh->cd();
	hist_a->Draw();
	hist_b->Draw("same");

	// Final formatting & output
	canv->SetLeftMargin(2.5); canv->SetRightMargin(2.5);
	std::string outputLocationStr(outputLocation);
	canv->SaveAs((outputLocationStr + ".pdf").c_str());
	canv->SaveAs((outputLocationStr + ".png").c_str());
	canv->SaveAs((outputLocationStr + ".C").c_str());
}

So it crashes whenever I pass it a figureTitle that contains latex (eg. “#pi”), although figureXLabel is able to handle latex just fine. Here is a copy of the error message produced:

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x000000368b0ac89e in waitpid () from /lib64/libc.so.6
#1  0x000000368b03e4e9 in do_system () from /lib64/libc.so.6
#2  0x00007f6181f5febd in TUnixSystem::StackTrace() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libCore.so
#3  0x00007f6181f62624 in TUnixSystem::DispatchSignals(ESignals) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libCore.so
#4  <signal handler called>
#5  0x00007f6173e59ade in FT_Done_Glyph () from /cvmfs/sft.cern.ch/lcg/releases/LCG_94/freetype/2.6.3/x86_64-slc6-gcc62-opt/lib/libfreetype.so.6
#6  0x00007f61741c7191 in TTF::LayoutGlyphs() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#7  0x00007f61741c784f in TTF::GetTextExtent(unsigned int&, unsigned int&, char*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#8  0x00007f61741916c4 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#9  0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#10 0x00007f617418d1b7 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#11 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#12 0x00007f617418b5bf in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#13 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#14 0x00007f617418b625 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#15 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#16 0x00007f61741943ff in TLatex::FirstParse(double, double, char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#17 0x00007f6174196895 in TLatex::GetYsize() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#18 0x00007f6170e736e1 in THistPainter::PaintTitle() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libHistPainter.so
#19 0x00007f6170e60b0a in THistPainter::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libHistPainter.so
#20 0x00007f61744dba6c in TPad::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#21 0x00007f61744dba6c in TPad::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#22 0x00007f61744d850f in TPad::Print(char const*, char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#23 0x00007f61744d91ce in TPad::SaveAs(char const*, char const*) const () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#24 0x00007f618187a191 in ?? ()
#25 0x0000000000000000 in ?? ()
===========================================================


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  0x00007f6173e59ade in FT_Done_Glyph () from /cvmfs/sft.cern.ch/lcg/releases/LCG_94/freetype/2.6.3/x86_64-slc6-gcc62-opt/lib/libfreetype.so.6
#6  0x00007f61741c7191 in TTF::LayoutGlyphs() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#7  0x00007f61741c784f in TTF::GetTextExtent(unsigned int&, unsigned int&, char*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#8  0x00007f61741916c4 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#9  0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#10 0x00007f617418d1b7 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#11 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#12 0x00007f617418b5bf in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#13 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#14 0x00007f617418b625 in TLatex::Analyse(double, double, TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#15 0x00007f6174194271 in TLatex::Anal1(TLatex::TextSpec_t, char const*, int) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#16 0x00007f61741943ff in TLatex::FirstParse(double, double, char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#17 0x00007f6174196895 in TLatex::GetYsize() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGraf.so
#18 0x00007f6170e736e1 in THistPainter::PaintTitle() () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libHistPainter.so
#19 0x00007f6170e60b0a in THistPainter::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libHistPainter.so
#20 0x00007f61744dba6c in TPad::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#21 0x00007f61744dba6c in TPad::Paint(char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#22 0x00007f61744d850f in TPad::Print(char const*, char const*) () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#23 0x00007f61744d91ce in TPad::SaveAs(char const*, char const*) const () from /cvmfs/sft.cern.ch/lcg/releases/ROOT/6.14.04-0d8dc/x86_64-slc6-gcc62-opt/lib/libGpad.so
#24 0x00007f618187a191 in ?? ()
#25 0x0000000000000000 in ?? ()
===========================================================

Thanks,
Dylan

I do not see any #pi in you code. I will try to make a reproducer.

it works for me:

root [0] auto h1 = new TH1D("h1","#pi",100,0,1); 
root [1] h1->Draw()
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [2] c1->SaveAs("h1.png");
Info in <TCanvas::Print>: file h1.png has been created
root [3] 

I am also able to get this simple example in the terminal to work. But when my script calls the function I showed above, that’s when it crashes.

There is no “#pi” hard-coded in to this function, it’s something to pass as an argument for ‘figureTitle’. However I tried editing the line “hist_a->SetTitle(figureTitle);” to “hist_a->SetTitle(”#pi");" and that still causes it to crash when it reaches the SaveAs line.

Upon further testing I seem to also be getting these errors when I try to draw the canvas:

 Fontconfig error: Cannot load default config file
Warning in <TPad::ResizePad>: Inf/NaN propagated to the pad. Check drawn objects.
Warning in <TPad::ResizePad>: padh height changed from 0 to 10

Cab you provide a small macro reproducing the problem ?

I seem to have resolved the problem for all practical purposes. I was selecting only the first few thousand events from my NTuple, which was ordered, so the first plot had 0 entries. (This still doesn’t explain why it was happy to draw an empty figure only when I removed the latex script from the title however). Thank you for your help nonetheless!

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