Re: TCanvas crash in GUI

From: Ilka Antcheva <Ilka.Antcheva_at_cern.ch>
Date: Wed, 29 Aug 2007 10:01:06 +0200


Hi Tom,

I can reproduce the crash using ROOT version 5.12. The same test case works fine with CVS head, if I exit ROOT version selecting File menu / Quit ROOT. The reason is in the way of registering/handling the object editors in ROOT after the version 5.12.

Below you can see the output I got:


Compiled on 28 August 2007 for linux with thread support.

CINT/ROOT C/C++ Interpreter version 5.16.24, July 26, 2007 Type ? for help. Commands must be C++ statements. Enclose multiple statements between { }. root [0] .x test.C
Detaching after fork from child process 13589. root [1] Plot() creating new TCanvas name='Plot1'

Plot()  OK
Plot() creating new TCanvas  name='Plot2'
Plot()  OK
Plot() creating new TCanvas  name='Plot3'
Plot()  OK
plotClosed(Plot2)
plotClosed(Plot2)

plotClosed(Plot3)
plotClosed(Plot3)
Plot() creating new TCanvas name='Plot4' Plot() OK

Program exited normally.


I see crash only when using .q, but trace back does not show anything related to the GUI code. We will investigate the reasons. You can see the bt below.



...
Plot() creating new TCanvas name='Plot4' Plot() OK
.q

Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1218558176 (LWP 13414)] 0x00302239 in free () from /lib/tls/libc.so.6 (gdb) bt
#0 0x00302239 in free () from /lib/tls/libc.so.6

#1  0x00cf3646 in G__destroy_upto_vararray (var=0xa3e3660, global=1, ig15=0)
     at cint/src/v6_scrupto.cxx:672
#2  0x00cf3836 in G__destroy_upto (var=0xa2401e8, global=1, 
dictpos=0xa2401e8, ig15=1)
     at cint/src/v6_scrupto.cxx:756

#3 0x00cf3049 in G__scratch_globals_upto (dictpos=0xa0ce1b0) at cint/src/v6_scrupto.cxx:518
#4 0x0069e472 in TCint::ResetGlobals (this=0xa0ce110) at meta/src/TCint.cxx:441
#5 0x005f3692 in TApplication::ProcessLine (this=0xa0f1c50, line=0xa2bb570 ".q", sync=false,

     err=0x0) at base/src/TApplication.cxx:671 #6 0x00125223 in TRint::HandleTermInput (this=0xa0f1c50) at rint/src/TRint.cxx:514
#7 0x00123250 in TTermInputHandler::Notify (this=0xa21e0b8) at rint/src/TRint.cxx:122
#8 0x001262f2 in TTermInputHandler::ReadNotify (this=0xa21e0b8) at rint/src/TRint.cxx:114
#9 0x006d4045 in TUnixSystem::CheckDescriptors (this=0xa0cb118) at unix/src/TUnixSystem.cxx:1086
#10 0x006d33a2 in TUnixSystem::DispatchOneEvent (this=0xa0cb118, pendingOnly=false)

     at unix/src/TUnixSystem.cxx:785
#11 0x0065c50c in TSystem::InnerLoop (this=0xa0cb118) at base/src/TSystem.cxx:356
#12 0x0065c49a in TSystem::Run (this=0xa0cb118) at base/src/TSystem.cxx:324 #13 0x005f4786 in TApplication::Run (this=0xa0f1c50, retrn=false) at base/src/TApplication.cxx:902
#14 0x00124ada in TRint::Run (this=0xa0f1c50, retrn=false) at rint/src/TRint.cxx:369
#15 0x0804894a in main (argc=1, argv=0xbfffaaf4) at main/src/rmain.cxx:29

Cheers, Ilka

Tom Roberts wrote:

> The attached program will regularly crash on Linux, and will hang at the 
> same place in Windows (burning CPU time); it works fine in Mac OS X 
> (Intel).
> 
> To run it, save it to some directory and do:
>     root test.C
> It will pop up a small dialog box -- move it away from where new windows 
> are created. Then push "Create Plot" three times, which will create 
> three plot windows on top of each other. Move the "Plot 3" window down a 
> bit and close the "Plot 2" window (via the usual window control). Then 
> close the "Plot 3" window, leaving "Plot 1" open. Now push "Create Plot" 
> and watch the crash or hang. It takes a complicated sequence of window 
> opens and closes to trigger the crash, and this is the simplest I have 
> found (if it didn't crash yet, do a ".q" to see one [not on Mac OS X]).
> 
> On Linux the output is:
>   *******************************************
>   *                                         *
>   *        W E L C O M E  to  R O O T       *
>   *                                         *
>   *   Version   5.12/00      10 July 2006   *
>   *                                         *
>   *  You are welcome to visit our Web site  *
>   *          http://root.cern.ch            *
>   *                                         *
>   *******************************************
> 
> FreeType Engine v2.1.9 used to render TrueType fonts.
> Compiled on 11 July 2006 for linux with thread support.
> 
> CINT/ROOT C/C++ Interpreter version 5.16.13, June 8, 2006
> Type ? for help. Commands must be C++ statements.
> Enclose multiple statements between { }.
> root [0]
> Processing test.C...
> root [1] Plot() creating new TCanvas  name='Plot1'
> Plot()  OK
> Plot() creating new TCanvas  name='Plot2'
> Plot()  OK
> Plot() creating new TCanvas  name='Plot3'
> Plot()  OK
> plotClosed(Plot2)
> plotClosed(Plot2)
> plotClosed(Plot2)
> plotClosed(Plot3)
> plotClosed(Plot3)
> plotClosed(Plot3)
> Plot() creating new TCanvas  name='Plot4'
> 
>  *** Break *** segmentation violation
>  Generating stack trace...
>  0x04191a6d in <unknown> from /usr/lib/libstdc++.so.6
>  0x01a75967 in TGedEditor::GetBaseClassEditor(TClass*) + 0x7d from 
> /home/tjrob/root/lib/libGed.so
>  0x01a740e4 in TGedEditor::GetEditors() + 0x228 from 
> /home/tjrob/root/lib/libGed.so
>  0x01a74680 in TGedEditor::TGedEditor(TCanvas*) + 0x528 from 
> /home/tjrob/root/lib/libGed.so
>  0x01b24556 in <unknown> from /home/tjrob/root/lib/libGed.so
> ....
> 
> 
> That trace gives a hint that this is related to the editor. If I comment 
> out line 90 [gEnv->SetValue("Canvas.ShowEditor",1);] it now seems to 
> work fine on all 3 OSs.
> 
> 
> Note the three calls to plotClosed() are worrisome (only 2 on Windows 
> and Mac OS). I do not know if that is related to this problem or not. 
> It's also curious that the histogram looks the same on Windows and Mac 
> OS X, but is different on Linux (even when Windows and Linux are running 
> on VMs under VMware/Mac, so this is not the CPU).
> 
> This is using Root 5.12. On Linux, root 5.16 did not crash for the above 
> sequence, but did crash on an immediately following ".q" (!); a much 
> more complicated sequence of "Create Plot" and close window did elicit a 
> crash as above. My primary application is linked with 5.12 so that is 
> the version I normally use.
> 
> 
> Tom Roberts
> 
> 
> ------------------------------------------------------------------------
> 
> // test.C
> 
> #include <TGClient.h>	// force Root to load libGui.
> 
> /** class Plot is a single plot
>  **/
> class Plot {
> 	RQ_OBJECT("Plot")
> 	char name[16];
> 	TNtuple *ntuple;
> 	TCanvas *canvas;
> 	TH1D *th1d;
> 	static int number;
> public:
> 	/// Constructor.
> 	Plot(TNtuple *_ntuple);
> 
> 	/// Destructor.
> 	virtual ~Plot();
> 
> 	/// plotClosed() is connected to CloseWindow() of Plot window.
> 	void plotClosed() {
> 		printf("plotClosed(%s)\n",name);
> 	}
> };
> int Plot::number=0;
> 
> Plot::Plot(TNtuple *_ntuple)
> {
> 	sprintf(name,"Plot%d",++number);
> 	ntuple = _ntuple;
> 	canvas = 0;
> 	th1d = 0;
> 
> 	// draw the plot in its own window (canvas)
> printf("Plot() creating new TCanvas  name='%s'\n",name); fflush(stdout);
> 	canvas = new TCanvas(name,name);
> printf("Plot()  OK\n"); fflush(stdout);
> 	canvas->SetFolder(true);
> 	canvas->Connect("Closed()","Plot",this,"plotClosed()");
> 	th1d = new TH1D(name,name,100,0.0,1.0);
> 	// a very simple filling of the histogram
> 	int n=100;
> 	for(int i=0; i<n; ++i) {
> 		double x=(double)i/(double)n;
> 		th1d->Fill(x);
> 	}
> 	th1d->Draw("");
> 	canvas->Selected(canvas,canvas->FindObject(th1d),1);
> }
> 
> Plot::~Plot()
> {
> 	if(canvas) canvas->Disconnect();
> 	// cannot delete canvas, because closing the window already did that
> 	canvas = 0;
> }
> 
> 
> /**	class Test is a test window for opening/closing Plot windows.
>  **/
> class Test {
> 	RQ_OBJECT("Test")
> private:
> 	TGMainFrame *window;
> public:
> 	/// Constructor (defaults work fine)
> 	Test(const TGWindow *win=0, UInt_t width=0, UInt_t height=0);
> 
> 	/// Destructor.
> 	virtual ~Test();
> 
> 	/// command() is Connect-ed to all of the signals
> 	static void command(Int_t);
> };
> void Test::command(Int_t id)
> {
> 	switch(id) {
> 	case 50:
> 		new Plot(0);
> 		break;
> 	case 99:
> 		gApplication->Terminate(0);
> 	}
> }
> 
> Test::Test(const TGWindow *win, UInt_t width, UInt_t height)
> {
> 	// have all new canvases show the editor initially.
> 	gEnv->SetValue("Canvas.ShowEditor",1);
> 
> 	if(win == 0) win = gClient->GetRoot();
> 	if(width <= 0) width = 200;
> 	if(height <= 0) height = 200;
> 	window = new TGMainFrame(win,width,height,kVerticalFrame);
> 
> 	// Layout the main Test window
> 	TGTextButton *create = new TGTextButton(window,"Create Plot",50);
> 	window->AddFrame(create,new TGLayoutHints(kLHintsCenterX,20,20,20,20));
> 	create->SetCommand("Test::command(50)");
> 
> 	// display window
> 	window->Connect("CloseWindow()","Test",this,"command(=99)");
> 	window->Layout();
> 	window->SetWindowName("Test");
> 	window->MapSubwindows();
> 	window->Resize(window->GetDefaultSize());
> 	window->MapWindow();
> }
> 
> Test::~Test()
> {
> 	if(!window) return;
> 	window->Cleanup();
> 	// cannot delete window, as closing it already did that
> 	window = 0;
> }
> 
> // Root has problems with the default optimization level ".O 4"
> void test() { gROOT->ProcessLine(".O 3"); new Test(); }
Received on Wed Aug 29 2007 - 10:01:19 CEST

This archive was generated by hypermail 2.2.0 : Wed Aug 29 2007 - 11:50:01 CEST