GUI crashes when display not set

Dear All,

I am writing some code for an Event Display GUI. The code is on a remote server that I connect to with ssh. The GUI works fine when I use ssh -X to to set the DISPLAY variable properly. However, when I omit the ‘-X’, DISPLAY is null, and the GUI encounters a segmentation violation. I’ve posted the code and the error below. You can see that I tried including some code to exit before the crash, but it still does not work. Can anyone see why the GUI would crash? Ideally I would like it to exit with an error message about the display instead of crashing.
System details: I’m running Red Hat Scientific Linux 4.3, using gcc version 3.4.6, and root 5.19. The full GUI code (~600 lines) is included as an attachment.

Error Message

[simons@hydrogen make]$ EXOEventDisplay
Warning in <TUnixSystem::SetDisplay>: DISPLAY not set, setting it to dhcpvisitor218217.slac.stanford.edu:0.0
Using displaydhcpvisitor218217.slac.stanford.edu:0.0.
Error in <TGVScrollBar::TGVScrollBar>: arrow_*.xpm not found
Warning in <TCanvas::ResizePad>: Ecanvas width changed from 0 to 10

Warning in <TCanvas::ResizePad>: Ecanvas height changed from 0 to 10

Error in <TGRadioButton::TGRadioButton>: rbutton_*.xpm not found

 *** Break *** segmentation violation
Using host libthread_db library "/lib/tls/libthread_db.so.1".
Attaching to program: /proc/17179/exe, process 17179
[Thread debugging using libthread_db enabled]
[New Thread -1208575776 (LWP 17179)]
0x00ada7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1  0x073c5ff3 in __waitpid_nocancel () from /lib/tls/libc.so.6
#2  0x07370469 in do_system () from /lib/tls/libc.so.6
#3  0x0525984d in system () from /lib/tls/libpthread.so.0
#4  0x002d514b in TUnixSystem::Exec ()
   from /nuchome/software/root/5.19/root/lib/libCore.so
#5  0x002dabf9 in TUnixSystem::StackTrace ()
   from /nuchome/software/root/5.19/root/lib/libCore.so
#6  0x002d7816 in TUnixSystem::DispatchSignals ()
   from /nuchome/software/root/5.19/root/lib/libCore.so
#7  0x002d78a4 in SigHandler ()
   from /nuchome/software/root/5.19/root/lib/libCore.so
#8  0x002d6af1 in sighandler ()
   from /nuchome/software/root/5.19/root/lib/libCore.so
#9  <signal handler called>
#10 0x05aeb062 in TGRadioButton::GetDefaultSize ()
   from /nuchome/software/root/5.19/root/lib/libGui.so
#11 0x05b32d4e in TGFrame::Resize ()
   from /nuchome/software/root/5.19/root/lib/libGui.so
#12 0x05aea868 in TGRadioButton::Init ()
   from /nuchome/software/root/5.19/root/lib/libGui.so
#13 0x05aeaac8 in TGRadioButton::TGRadioButton ()
   from /nuchome/software/root/5.19/root/lib/libGui.so
#14 0x08050a62 in EXOEventDisplayGui (this=0x9d6a8b8, p=0x9b4f9b0, w=200,
    h=200, FILENAME=0x0)
    at /nuchome/software/root/5.19/root/include/TObject.h:156
#15 0x0804e34b in main (argc=1, argv=0xbfe66b04)
    at /nuchome/simons/31dec2009subversion/offline/consumers/eventdisplay/src/EXOEventDisplay.cc:35

Calls the GUI

#include "EXOEventDisplayGui.hh"
#include <TApplication.h>
#include <TGClient.h>
#include <iostream>
using namespace std;

int main( int argc, char **argv )

{

  // Print out an error if the user's display is not set properly.         
  // Doesn't work since Root tries to force setting DISPLAY before this co\
de runs.                                                                   
  char * display;
  display = getenv("DISPLAY");
  if (display!=NULL)
    cout << "Using display" << display << "." << endl;
  else {
    cout << "Display not setup properly. Please open an X-terminal and try\
 agai\                                                                     
n. If you are using ssh, disconnect and ssh again with the option '-X', as\
 in\                                                                       
 ssh -X <your username>@<your host>." << endl;
    exit(1);
  }

 if ( argc > 1 ) {
    char filename[200];
    strncpy(filename,argv[1],199);
    TApplication theApp("App",&argc,argv);
    new EXOEventDisplayGui( gClient->GetRoot(), 200, 200, filename );
    theApp.Run();
  }
  else {
    TApplication theApp("App",&argc,argv);
    new EXOEventDisplayGui( gClient->GetRoot(), 200, 200, NULL );
    theApp.Run();
  }

  return 0;

}


This is part of the GUI itself. I’ve included the both the beginning of the code and the part of the GUI where the crash occurs, with … separating the two sections.

#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TH2.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TRootEmbeddedCanvas.h>
#include <TStyle.h>
#include "EXOEventDisplayGui.hh"
#include "EXOUtilities/EXOErrorLogger.hh"
#include "EXOUtilities/EXOTalkToManager.hh"
#include "EXOUtilities/EXOEventData.hh"
#include "EXOAnalysisManager/EXOAnalysisManager.hh"
#include "EXOAnalysisManager/EXOAnalysisModule.hh"
#include "EXOAnalysisManager/EXOBinaryFileInputModule.hh"
#include "EXOAnalysisManager/EXOTreeInputModule.hh"
#ifndef NOG4
#include "EXOAnalysisManager/EXOGeant4Module.hh"
#endif
#include "EXOAnalysisManager/EXOExampleModule.hh"
#include "EXOAnalysisManager/EXOReconstructionModule.hh"
#include "EXOAnalysisManager/EXOTreeOutputModule.hh"
#include "EXOAnalysisManager/EXOBinaryFileOutputModule.hh"
#include "EXOAnalysisManager/EXOEventDumpModule.hh"
#include "EXOAnalysisManager/EXODataTrimModule.hh"
#include <iostream>

using namespace std;

......
......
......

fEcanvas = new TRootEmbeddedCanvas("Ecanvas",fTopFrame,600,600);
  fTopFrame->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandY|kLHintsEx\
pandX,200,2,2,2));

  //Create a group of radio buttons in a vertical frame                    

  radiobg = new TGVButtonGroup(fTopFrame,"Plot Style");
  fpage[0] = new TGRadioButton(radiobg, new TGHotString("Color"));
  fpage[1] = new TGRadioButton(radiobg, new TGHotString("Greyscale"));
  fpage[0]->SetState(kButtonDown); //Need to draw raw signals vs time      
  radiobg->Connect("Clicked(Int_t)","EXOEventDisplayGui",this,"PushedPlotS\
tyleButton(Int_t)");
  radiobg->Show();

  //draw first entry of file when display is launched                      

  if ( filename != NULL ) GetDataSource();

  fMain->SetWindowName("EXO Event Display");

  fMain->MapSubwindows();

Full GUI code.
EventDisplayGUI.txt (20.2 KB)

Hi,

What about this:

   TApplication theApp("App",&argc,argv); 
   if (gROOT->IsBatch()) {
      fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]);
      return 1;
   }
   ...

Since ROOT should be set in batch mode when no display is available…

Cheers, Bertrand.

Hi, Bertrand,

I’m not sure that helps; the error message seems to imply that the display is in fact being set somehow. Here is the segment that make me think that:

Warning in <TUnixSystem::SetDisplay>: DISPLAY not set, setting it to dhcpvisitor218217.slac.stanford.edu:0.0
Using displaydhcpvisitor218217.slac.stanford.edu:0.0. 

Any thoughts as to why the program should crash in the first place?

– Simon

Hi Simon,

Did you try? :confused: I tried with $ROOTSYS/test/guitest via ssh and it was reproducing the behavior you see. I was not able to try your code, since you provided only part of it…

Well, I’m not really a X11 specialist, but setting a display which may not be valid (e.g. via ssh) and trying to use it may lead to a crash (just guessing…)
This is the reason of the few lines of code I sent to you.

Cheers, Bertrand.