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

#include <InitRootHandlers.h>

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_
 
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 17 of file InitRootHandlers.h.

Constructor & Destructor Documentation

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

Definition at line 491 of file InitRootHandlers.cc.

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

492  : RootHandlers(),
493  unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler")),
494  resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler")),
495  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
496  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool> ("AutoLibraryLoader"))
497  {
498 
499  if(unloadSigHandler_) {
500  // Deactivate all the Root signal handlers and restore the system defaults
501  gSystem->ResetSignal(kSigChild);
502  gSystem->ResetSignal(kSigBus);
503  gSystem->ResetSignal(kSigSegmentationViolation);
504  gSystem->ResetSignal(kSigIllegalInstruction);
505  gSystem->ResetSignal(kSigSystem);
506  gSystem->ResetSignal(kSigPipe);
507  gSystem->ResetSignal(kSigAlarm);
508  gSystem->ResetSignal(kSigUrgent);
509  gSystem->ResetSignal(kSigFloatingException);
510  gSystem->ResetSignal(kSigWindowChanged);
511  } else if(pset.getUntrackedParameter<bool>("AbortOnSignal")){
512  cachePidInfo();
513 
514  //NOTE: ROOT can also be told to abort on these kinds of problems BUT
515  // it requires an TApplication to be instantiated which causes problems
516  gSystem->ResetSignal(kSigBus);
517  gSystem->ResetSignal(kSigSegmentationViolation);
518  gSystem->ResetSignal(kSigIllegalInstruction);
519  installCustomHandler(SIGBUS,sig_dostack_then_abort);
520  sigBusHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
521  installCustomHandler(SIGBUS,sig_abort);
522  });
523  installCustomHandler(SIGSEGV,sig_dostack_then_abort);
524  sigSegvHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
525  installCustomHandler(SIGSEGV,sig_abort);
526  });
527  installCustomHandler(SIGILL,sig_dostack_then_abort);
528  sigIllHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
529  installCustomHandler(SIGILL,sig_abort);
530  });
531  iReg.watchPostForkReacquireResources(this, &InitRootHandlers::cachePidInfoHandler);
532  }
533 
534  if(resetErrHandler_) {
535 
536  // Replace the Root error handler with one that uses the MessageLogger
537  SetErrorHandler(RootErrorHandler);
538  }
539 
540  // Enable automatic Root library loading.
541  if(autoLibraryLoader_) {
542  gInterpreter->SetClassAutoloading(1);
543  }
544 
545  // Set ROOT parameters.
546  TTree::SetMaxTreeSize(kMaxLong64);
547  TH1::AddDirectory(kFALSE);
548  //G__SetCatchException(0);
549 
550  // Set custom streamers
552 
553  // Load the library containing dictionaries for std:: classes, if not already loaded.
554  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
555  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
556  }
557 
558  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
559  if(debugLevel >0) {
560  gDebug = debugLevel;
561  }
562  }
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_
bool hasDictionary(std::type_info const &)
edm::service::InitRootHandlers::~InitRootHandlers ( )
virtual

Definition at line 564 of file InitRootHandlers.cc.

References f, and getGTfromDQMFile::obj.

564  {
565  // close all open ROOT files
566  TIter iter(gROOT->GetListOfFiles());
567  TObject *obj = nullptr;
568  while(nullptr != (obj = iter.Next())) {
569  TFile* f = dynamic_cast<TFile*>(obj);
570  if(f) {
571  // We get a new iterator each time,
572  // because closing a file can invalidate the iterator
573  f->Close();
574  iter = TIter(gROOT->GetListOfFiles());
575  }
576  }
577  }
double f[11][100]

Member Function Documentation

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

Definition at line 627 of file InitRootHandlers.cc.

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

Referenced by cachePidInfoHandler(), and InitRootHandlers().

628  {
629  if (snprintf(pidString_, pidStringLength_-1, "gdb -quiet -p %d 2>&1 <<EOF |\n"
630  "set width 0\n"
631  "set height 0\n"
632  "set pagination no\n"
633  "thread apply all bt\n"
634  "EOF\n"
635  "/bin/sed -n -e 's/^\\((gdb) \\)*//' -e '/^#/p' -e '/^Thread/p'", getpid()) >= pidStringLength_)
636  {
637  std::ostringstream sstr;
638  sstr << "Unable to pre-allocate stacktrace handler information";
639  edm::Exception except(edm::errors::OtherCMS, sstr.str());
640  throw except;
641  }
642 
643  // These are initialized to -1; harmless to close an invalid FD.
644  // If this is called post-fork, we don't want to be communicating on
645  // these FDs as they are used internally by the parent.
646  close(childToParent_[0]);
647  close(childToParent_[1]);
648  childToParent_[0] = -1; childToParent_[1] = -1;
649  close(parentToChild_[0]);
650  close(parentToChild_[1]);
651  parentToChild_[0] = -1; parentToChild_[1] = -1;
652 
653  if (-1 == pipe2(childToParent_, O_CLOEXEC))
654  {
655  std::ostringstream sstr;
656  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
657  edm::Exception except(edm::errors::OtherCMS, sstr.str());
658  throw except;
659  }
660 
661  if (-1 == pipe2(parentToChild_, O_CLOEXEC))
662  {
663  close(childToParent_[0]); close(childToParent_[1]);
664  childToParent_[0] = -1; childToParent_[1] = -1;
665  std::ostringstream sstr;
666  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
667  edm::Exception except(edm::errors::OtherCMS, sstr.str());
668  throw except;
669  }
670 
671  helperThread_.reset(new std::thread(stacktraceHelperThread));
672  helperThread_->detach();
673  }
static char pidString_[pidStringLength_]
static std::unique_ptr< std::thread > helperThread_
void edm::service::InitRootHandlers::cachePidInfoHandler ( unsigned  int,
unsigned  int 
)
inlineprivate

Definition at line 35 of file InitRootHandlers.h.

References cachePidInfo().

Referenced by InitRootHandlers().

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

Implements edm::RootHandlers.

Definition at line 617 of file InitRootHandlers.cc.

617  {
618  s_ignoreWarnings =false;
619  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 593 of file InitRootHandlers.cc.

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

593  {
595  desc.setComment("Centralized interface to ROOT.");
596  desc.addUntracked<bool>("UnloadRootSigHandler", false)
597  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
598  desc.addUntracked<bool>("ResetRootErrHandler", true)
599  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
600  desc.addUntracked<bool>("AutoLibraryLoader", true)
601  ->setComment("If True, enables automatic loading of data dictionaries.");
602  desc.addUntracked<bool>("LoadAllDictionaries",false)
603  ->setComment("If True, loads all ROOT dictionaries.");
604  desc.addUntracked<bool>("AbortOnSignal",true)
605  ->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.");
606  desc.addUntracked<int>("DebugLevel",0)
607  ->setComment("Sets ROOT's gDebug value.");
608  descriptions.add("InitRootHandlers", desc);
609  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 612 of file InitRootHandlers.cc.

References pstackArgv_.

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

612  {
613  return pstackArgv_;
614  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 622 of file InitRootHandlers.cc.

622  {
623  s_ignoreWarnings = true;
624  }
void edm::service::InitRootHandlers::initializeThisThreadForUse ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 589 of file InitRootHandlers.cc.

589  {
590  static thread_local TThread guard;
591  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 407 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and query::result.

408  {
409  int result = full_write(parentToChild_[1], "1");
410  if (result < 0)
411  {
412  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
413  full_cerr_write(strerror(-result));
414  full_cerr_write("\n");
415  return;
416  }
417  char buf[2]; buf[1] = '\0';
418  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
419  {
420  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
421  if (result == -ETIMEDOUT)
422  {
423  full_cerr_write("timed out waiting for GDB to complete.");
424  }
425  else
426  {
427  full_cerr_write(strerror(-result));
428  }
429  full_cerr_write("\n");
430  return;
431  }
432  }
tuple result
Definition: query.py:137
void edm::service::InitRootHandlers::stacktraceHelperThread ( )
staticprivate

Definition at line 356 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

357  {
358  int toParent = childToParent_[1];
359  int fromParent = parentToChild_[0];
360  char buf[2]; buf[1] = '\0';
361  while(true)
362  {
363  int result = full_read(fromParent, buf, 1);
364  if (result < 0)
365  {
366  // To avoid a deadlock (this function is NOT re-entrant), reset signals
367  // We never set them back to the CMSSW handler because we assume the parent
368  // thread will abort for us.
369  set_default_signals();
370  close(toParent);
371  full_cerr_write("\n\nTraceback helper thread failed to read from parent: ");
372  full_cerr_write(strerror(-result));
373  full_cerr_write("\n");
374  ::abort();
375  }
376  if (buf[0] == '1')
377  {
378  set_default_signals();
380  full_write(toParent, buf);
381  }
382  else if (buf[0] == '2')
383  {
384  // We have just finished forking. Reload the file descriptors for thread
385  // communication.
386  close(toParent);
387  close(fromParent);
388  toParent = childToParent_[1];
389  fromParent = parentToChild_[0];
390  }
391  else if (buf[0] == '3')
392  {
393  break;
394  }
395  else
396  {
397  set_default_signals();
398  close(toParent);
399  full_cerr_write("\n\nTraceback helper thread got unknown command from parent: ");
400  full_cerr_write(buf);
401  full_cerr_write("\n");
402  ::abort();
403  }
404  }
405  }
static void cmssw_stacktrace_fork()
tuple result
Definition: query.py:137
void edm::service::InitRootHandlers::willBeUsingThreads ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 579 of file InitRootHandlers.cc.

579  {
580  //Tell Root we want to be multi-threaded
581  TThread::Initialize();
582  //When threading, also have to keep ROOT from logging all TObjects into a list
583  TObject::SetObjectStat(false);
584 
585  //Have to avoid having Streamers modify themselves after they have been used
586  TVirtualStreamerInfo::Optimize(false);
587  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Member Data Documentation

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

Definition at line 48 of file InitRootHandlers.h.

Referenced by InitRootHandlers().

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

Definition at line 43 of file InitRootHandlers.h.

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

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

Definition at line 44 of file InitRootHandlers.h.

Referenced by cachePidInfo().

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

Definition at line 47 of file InitRootHandlers.h.

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

Definition at line 42 of file InitRootHandlers.h.

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

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

Definition at line 40 of file InitRootHandlers.h.

Referenced by cachePidInfo().

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

Definition at line 39 of file InitRootHandlers.h.

Referenced by cachePidInfo().

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

Definition at line 41 of file InitRootHandlers.h.

Referenced by getPstackArgv().

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

Definition at line 46 of file InitRootHandlers.h.

Referenced by InitRootHandlers().

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

Definition at line 49 of file InitRootHandlers.h.

Referenced by InitRootHandlers().

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

Definition at line 51 of file InitRootHandlers.h.

Referenced by InitRootHandlers().

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

Definition at line 50 of file InitRootHandlers.h.

Referenced by InitRootHandlers().

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

Definition at line 45 of file InitRootHandlers.h.

Referenced by InitRootHandlers().