CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends
edm::service::InitRootHandlers Class Reference
Inheritance diagram for edm::service::InitRootHandlers:
edm::RootHandlers

Public Member Functions

 InitRootHandlers (ParameterSet const &pset, ActivityRegistry &iReg)
 
virtual ~InitRootHandlers ()
 
- Public Member Functions inherited from edm::RootHandlers
template<typename F >
void ignoreWarningsWhileDoing (F iFunc)
 
 RootHandlers ()
 
virtual ~RootHandlers ()
 

Static Public Member Functions

static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void stacktraceFromThread ()
 

Private Member Functions

void cachePidInfo ()
 
void cachePidInfoHandler (unsigned int, unsigned int)
 
virtual void enableWarnings_ () override
 
virtual void ignoreWarnings_ () override
 
virtual void initializeThisThreadForUse () override
 
virtual void willBeUsingThreads () override
 

Static Private Member Functions

static char *const * getPstackArgv ()
 
static void stacktraceHelperThread ()
 

Private Attributes

bool autoLibraryLoader_
 
bool loadAllDictionaries_
 
bool resetErrHandler_
 
std::shared_ptr< const void > sigBusHandler_
 
std::shared_ptr< const void > sigIllHandler_
 
std::shared_ptr< const void > sigSegvHandler_
 
std::shared_ptr< const void > sigTermHandler_
 
bool unloadSigHandler_
 

Static Private Attributes

static int childToParent_ [2] = {-1, -1}
 
static std::unique_ptr
< std::thread > 
helperThread_
 
static int parentToChild_ [2] = {-1, -1}
 
static char pidString_ [pidStringLength_] = {}
 
static const int pidStringLength_ = 200
 
static char *const pstackArgv_ [] = {pstackName, dashC, InitRootHandlers::pidString_, 0 }
 

Friends

int cmssw_stacktrace (void *)
 

Detailed Description

Definition at line 51 of file InitRootHandlers.cc.

Constructor & Destructor Documentation

edm::service::InitRootHandlers::InitRootHandlers ( ParameterSet const &  pset,
ActivityRegistry iReg 
)
explicit

Definition at line 559 of file InitRootHandlers.cc.

References autoLibraryLoader_, edm::TypeWithDict::byName(), cachePidInfo(), cachePidInfoHandler(), HLT_FULL_cff::debugLevel, edm::ParameterSet::getUntrackedParameter(), edm::hasDictionary(), edm::installCustomHandler(), resetErrHandler_, edm::setRefCoreStreamer(), sigBusHandler_, sigIllHandler_, sigSegvHandler_, sigTermHandler_, unloadSigHandler_, and edm::ActivityRegistry::watchPostForkReacquireResources().

560  : RootHandlers(),
561  unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler")),
562  resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler")),
563  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
564  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool> ("AutoLibraryLoader"))
565  {
566 
567  if(unloadSigHandler_) {
568  // Deactivate all the Root signal handlers and restore the system defaults
569  gSystem->ResetSignal(kSigChild);
570  gSystem->ResetSignal(kSigBus);
571  gSystem->ResetSignal(kSigSegmentationViolation);
572  gSystem->ResetSignal(kSigIllegalInstruction);
573  gSystem->ResetSignal(kSigSystem);
574  gSystem->ResetSignal(kSigPipe);
575  gSystem->ResetSignal(kSigAlarm);
576  gSystem->ResetSignal(kSigUrgent);
577  gSystem->ResetSignal(kSigFloatingException);
578  gSystem->ResetSignal(kSigWindowChanged);
579  } else if(pset.getUntrackedParameter<bool>("AbortOnSignal")){
580  cachePidInfo();
581 
582  //NOTE: ROOT can also be told to abort on these kinds of problems BUT
583  // it requires an TApplication to be instantiated which causes problems
584  gSystem->ResetSignal(kSigBus);
585  gSystem->ResetSignal(kSigSegmentationViolation);
586  gSystem->ResetSignal(kSigIllegalInstruction);
587  installCustomHandler(SIGBUS,sig_dostack_then_abort);
588  sigBusHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
589  installCustomHandler(SIGBUS,sig_abort);
590  });
591  installCustomHandler(SIGSEGV,sig_dostack_then_abort);
592  sigSegvHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
593  installCustomHandler(SIGSEGV,sig_abort);
594  });
595  installCustomHandler(SIGILL,sig_dostack_then_abort);
596  sigIllHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
597  installCustomHandler(SIGILL,sig_abort);
598  });
599  installCustomHandler(SIGTERM,sig_dostack_then_abort);
600  sigTermHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
601  installCustomHandler(SIGTERM,sig_abort);
602  });
603  iReg.watchPostForkReacquireResources(this, &InitRootHandlers::cachePidInfoHandler);
604  }
605 
606  if(resetErrHandler_) {
607 
608  // Replace the Root error handler with one that uses the MessageLogger
609  SetErrorHandler(RootErrorHandler);
610  }
611 
612  // Enable automatic Root library loading.
613  if(autoLibraryLoader_) {
614  gInterpreter->SetClassAutoloading(1);
615  }
616 
617  // Set ROOT parameters.
618  TTree::SetMaxTreeSize(kMaxLong64);
619  TH1::AddDirectory(kFALSE);
620  //G__SetCatchException(0);
621 
622  // Set custom streamers
624 
625  // Load the library containing dictionaries for std:: classes, if not already loaded.
626  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
627  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
628  }
629 
630  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
631  if(debugLevel >0) {
632  gDebug = debugLevel;
633  }
634  }
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setRefCoreStreamer(bool resetAll=false)
void installCustomHandler(int signum, CFUNC func)
std::shared_ptr< const void > sigSegvHandler_
std::shared_ptr< const void > sigBusHandler_
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:60
void cachePidInfoHandler(unsigned int, unsigned int)
std::shared_ptr< const void > sigIllHandler_
std::shared_ptr< const void > sigTermHandler_
bool hasDictionary(std::type_info const &)
edm::service::InitRootHandlers::~InitRootHandlers ( )
virtual

Definition at line 636 of file InitRootHandlers.cc.

References f, and getGTfromDQMFile::obj.

636  {
637  // close all open ROOT files
638  TIter iter(gROOT->GetListOfFiles());
639  TObject *obj = nullptr;
640  while(nullptr != (obj = iter.Next())) {
641  TFile* f = dynamic_cast<TFile*>(obj);
642  if(f) {
643  // We get a new iterator each time,
644  // because closing a file can invalidate the iterator
645  f->Close();
646  iter = TIter(gROOT->GetListOfFiles());
647  }
648  }
649  }
double f[11][100]

Member Function Documentation

void edm::service::InitRootHandlers::cachePidInfo ( )
private

Definition at line 699 of file InitRootHandlers.cc.

References childToParent_, helperThread_, edm::errors::OtherCMS, parentToChild_, pidString_, pidStringLength_, and stacktraceHelperThread().

Referenced by cachePidInfoHandler(), and InitRootHandlers().

700  {
701  if (snprintf(pidString_, pidStringLength_-1, "gdb -quiet -p %d 2>&1 <<EOF |\n"
702  "set width 0\n"
703  "set height 0\n"
704  "set pagination no\n"
705  "thread apply all bt\n"
706  "EOF\n"
707  "/bin/sed -n -e 's/^\\((gdb) \\)*//' -e '/^#/p' -e '/^Thread/p'", getpid()) >= pidStringLength_)
708  {
709  std::ostringstream sstr;
710  sstr << "Unable to pre-allocate stacktrace handler information";
711  edm::Exception except(edm::errors::OtherCMS, sstr.str());
712  throw except;
713  }
714 
715  // These are initialized to -1; harmless to close an invalid FD.
716  // If this is called post-fork, we don't want to be communicating on
717  // these FDs as they are used internally by the parent.
718  close(childToParent_[0]);
719  close(childToParent_[1]);
720  childToParent_[0] = -1; childToParent_[1] = -1;
721  close(parentToChild_[0]);
722  close(parentToChild_[1]);
723  parentToChild_[0] = -1; parentToChild_[1] = -1;
724 
725  if (-1 == pipe2(childToParent_, O_CLOEXEC))
726  {
727  std::ostringstream sstr;
728  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
729  edm::Exception except(edm::errors::OtherCMS, sstr.str());
730  throw except;
731  }
732 
733  if (-1 == pipe2(parentToChild_, O_CLOEXEC))
734  {
735  close(childToParent_[0]); close(childToParent_[1]);
736  childToParent_[0] = -1; childToParent_[1] = -1;
737  std::ostringstream sstr;
738  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
739  edm::Exception except(edm::errors::OtherCMS, sstr.str());
740  throw except;
741  }
742 
743  helperThread_.reset(new std::thread(stacktraceHelperThread));
744  helperThread_->detach();
745  }
static char pidString_[pidStringLength_]
static std::unique_ptr< std::thread > helperThread_
void edm::service::InitRootHandlers::cachePidInfoHandler ( unsigned  int,
unsigned  int 
)
inlineprivate

Definition at line 69 of file InitRootHandlers.cc.

References cachePidInfo().

Referenced by InitRootHandlers().

void edm::service::InitRootHandlers::enableWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 689 of file InitRootHandlers.cc.

689  {
690  s_ignoreWarnings =false;
691  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 665 of file InitRootHandlers.cc.

References edm::ConfigurationDescriptions::add(), edm::ParameterSetDescription::addUntracked(), and edm::ParameterSetDescription::setComment().

665  {
667  desc.setComment("Centralized interface to ROOT.");
668  desc.addUntracked<bool>("UnloadRootSigHandler", false)
669  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
670  desc.addUntracked<bool>("ResetRootErrHandler", true)
671  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
672  desc.addUntracked<bool>("AutoLibraryLoader", true)
673  ->setComment("If True, enables automatic loading of data dictionaries.");
674  desc.addUntracked<bool>("LoadAllDictionaries",false)
675  ->setComment("If True, loads all ROOT dictionaries.");
676  desc.addUntracked<bool>("AbortOnSignal",true)
677  ->setComment("If True, do an abort when a signal occurs that causes a crash. If False, ROOT will do an exit which attempts to do a clean shutdown.");
678  desc.addUntracked<int>("DebugLevel",0)
679  ->setComment("Sets ROOT's gDebug value.");
680  descriptions.add("InitRootHandlers", desc);
681  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 684 of file InitRootHandlers.cc.

References pstackArgv_.

Referenced by edm::service::cmssw_stacktrace().

684  {
685  return pstackArgv_;
686  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 694 of file InitRootHandlers.cc.

694  {
695  s_ignoreWarnings = true;
696  }
void edm::service::InitRootHandlers::initializeThisThreadForUse ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 661 of file InitRootHandlers.cc.

661  {
662  static thread_local TThread guard;
663  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 475 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

476  {
477  int result = full_write(parentToChild_[1], "1");
478  if (result < 0)
479  {
480  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
481  full_cerr_write(strerror(-result));
482  full_cerr_write("\n");
483  return;
484  }
485  char buf[2]; buf[1] = '\0';
486  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
487  {
488  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
489  if (result == -ETIMEDOUT)
490  {
491  full_cerr_write("timed out waiting for GDB to complete.");
492  }
493  else
494  {
495  full_cerr_write(strerror(-result));
496  }
497  full_cerr_write("\n");
498  return;
499  }
500  }
tuple result
Definition: mps_fire.py:95
void edm::service::InitRootHandlers::stacktraceHelperThread ( )
staticprivate

Definition at line 424 of file InitRootHandlers.cc.

References childToParent_, edm::service::cmssw_stacktrace_fork(), parentToChild_, and mps_fire::result.

Referenced by cachePidInfo().

425  {
426  int toParent = childToParent_[1];
427  int fromParent = parentToChild_[0];
428  char buf[2]; buf[1] = '\0';
429  while(true)
430  {
431  int result = full_read(fromParent, buf, 1);
432  if (result < 0)
433  {
434  // To avoid a deadlock (this function is NOT re-entrant), reset signals
435  // We never set them back to the CMSSW handler because we assume the parent
436  // thread will abort for us.
437  set_default_signals();
438  close(toParent);
439  full_cerr_write("\n\nTraceback helper thread failed to read from parent: ");
440  full_cerr_write(strerror(-result));
441  full_cerr_write("\n");
442  ::abort();
443  }
444  if (buf[0] == '1')
445  {
446  set_default_signals();
448  full_write(toParent, buf);
449  }
450  else if (buf[0] == '2')
451  {
452  // We have just finished forking. Reload the file descriptors for thread
453  // communication.
454  close(toParent);
455  close(fromParent);
456  toParent = childToParent_[1];
457  fromParent = parentToChild_[0];
458  }
459  else if (buf[0] == '3')
460  {
461  break;
462  }
463  else
464  {
465  set_default_signals();
466  close(toParent);
467  full_cerr_write("\n\nTraceback helper thread got unknown command from parent: ");
468  full_cerr_write(buf);
469  full_cerr_write("\n");
470  ::abort();
471  }
472  }
473  }
static void cmssw_stacktrace_fork()
tuple result
Definition: mps_fire.py:95
void edm::service::InitRootHandlers::willBeUsingThreads ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 651 of file InitRootHandlers.cc.

651  {
652  //Tell Root we want to be multi-threaded
653  TThread::Initialize();
654  //When threading, also have to keep ROOT from logging all TObjects into a list
655  TObject::SetObjectStat(false);
656 
657  //Have to avoid having Streamers modify themselves after they have been used
658  TVirtualStreamerInfo::Optimize(false);
659  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Member Data Documentation

bool edm::service::InitRootHandlers::autoLibraryLoader_
private

Definition at line 82 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

int edm::service::InitRootHandlers::childToParent_ = {-1, -1}
staticprivate

Definition at line 77 of file InitRootHandlers.cc.

Referenced by cachePidInfo(), stacktraceFromThread(), and stacktraceHelperThread().

std::unique_ptr< std::thread > edm::service::InitRootHandlers::helperThread_
staticprivate

Definition at line 78 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

bool edm::service::InitRootHandlers::loadAllDictionaries_
private

Definition at line 81 of file InitRootHandlers.cc.

int edm::service::InitRootHandlers::parentToChild_ = {-1, -1}
staticprivate

Definition at line 76 of file InitRootHandlers.cc.

Referenced by cachePidInfo(), stacktraceFromThread(), and stacktraceHelperThread().

char edm::service::InitRootHandlers::pidString_ = {}
staticprivate

Definition at line 74 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

const int edm::service::InitRootHandlers::pidStringLength_ = 200
staticprivate

Definition at line 73 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

char *const edm::service::InitRootHandlers::pstackArgv_ = {pstackName, dashC, InitRootHandlers::pidString_, 0 }
staticprivate

Definition at line 75 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

bool edm::service::InitRootHandlers::resetErrHandler_
private

Definition at line 80 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

std::shared_ptr<const void> edm::service::InitRootHandlers::sigBusHandler_
private

Definition at line 83 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

std::shared_ptr<const void> edm::service::InitRootHandlers::sigIllHandler_
private

Definition at line 85 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

std::shared_ptr<const void> edm::service::InitRootHandlers::sigSegvHandler_
private

Definition at line 84 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

std::shared_ptr<const void> edm::service::InitRootHandlers::sigTermHandler_
private

Definition at line 86 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

bool edm::service::InitRootHandlers::unloadSigHandler_
private

Definition at line 79 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().