CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Static Public Member Functions | Static Public Attributes | 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

Classes

class  ThreadTracker
 

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 ()
 
static int stackTracePause ()
 
static const ThreadTracker::Container_typethreadIDs ()
 

Static Public Attributes

static std::atomic< std::size_t > doneModules_
 
static std::vector< std::array< char, moduleBufferSize > > moduleListBuffers_
 
static std::atomic< std::size_t > nextModule_
 

Private Member Functions

void cachePidInfo ()
 
virtual void enableWarnings_ () override
 
virtual void ignoreWarnings_ () 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 }
 
static int stackTracePause_ = 300
 
static ThreadTracker threadTracker_
 

Friends

int cmssw_stacktrace (void *)
 

Detailed Description

Definition at line 64 of file InitRootHandlers.cc.

Constructor & Destructor Documentation

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

Definition at line 744 of file InitRootHandlers.cc.

References autoLibraryLoader_, edm::TypeWithDict::byName(), cachePidInfo(), UEAnalysisJets_cfi::debugLevel, edm::ParameterSet::getUntrackedParameter(), edm::hasDictionary(), edm::installCustomHandler(), edm::service::SystemBounds::maxNumberOfThreads(), moduleListBuffers_, resetErrHandler_, edm::setRefCoreStreamer(), sigBusHandler_, sigIllHandler_, sigSegvHandler_, sigTermHandler_, stackTracePause_, unloadSigHandler_, and edm::ActivityRegistry::watchPreallocate().

745  : RootHandlers(),
746  unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler")),
747  resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler")),
748  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
749  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool> ("AutoLibraryLoader"))
750  {
751  stackTracePause_ = pset.getUntrackedParameter<int> ("StackTracePauseTime");
752 
753  if(unloadSigHandler_) {
754  // Deactivate all the Root signal handlers and restore the system defaults
755  gSystem->ResetSignal(kSigChild);
756  gSystem->ResetSignal(kSigBus);
757  gSystem->ResetSignal(kSigSegmentationViolation);
758  gSystem->ResetSignal(kSigIllegalInstruction);
759  gSystem->ResetSignal(kSigSystem);
760  gSystem->ResetSignal(kSigPipe);
761  gSystem->ResetSignal(kSigAlarm);
762  gSystem->ResetSignal(kSigUrgent);
763  gSystem->ResetSignal(kSigFloatingException);
764  gSystem->ResetSignal(kSigWindowChanged);
765  } else if(pset.getUntrackedParameter<bool>("AbortOnSignal")){
766  cachePidInfo();
767 
768  //NOTE: ROOT can also be told to abort on these kinds of problems BUT
769  // it requires an TApplication to be instantiated which causes problems
770  gSystem->ResetSignal(kSigBus);
771  gSystem->ResetSignal(kSigSegmentationViolation);
772  gSystem->ResetSignal(kSigIllegalInstruction);
773  installCustomHandler(SIGBUS,sig_dostack_then_abort);
774  sigBusHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
775  installCustomHandler(SIGBUS,sig_abort);
776  });
777  installCustomHandler(SIGSEGV,sig_dostack_then_abort);
778  sigSegvHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
779  installCustomHandler(SIGSEGV,sig_abort);
780  });
781  installCustomHandler(SIGILL,sig_dostack_then_abort);
782  sigIllHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
783  installCustomHandler(SIGILL,sig_abort);
784  });
785  installCustomHandler(SIGTERM,sig_dostack_then_abort);
786  sigTermHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
787  installCustomHandler(SIGTERM,sig_abort);
788  });
789  }
790 
791  iReg.watchPreallocate([this](edm::service::SystemBounds const& iBounds){
792  if (iBounds.maxNumberOfThreads() > moduleListBuffers_.size()) {
793  moduleListBuffers_.resize(iBounds.maxNumberOfThreads());
794  }
795  });
796 
797  if(resetErrHandler_) {
798 
799  // Replace the Root error handler with one that uses the MessageLogger
800  SetErrorHandler(RootErrorHandler);
801  }
802 
803  // Enable automatic Root library loading.
804  if(autoLibraryLoader_) {
805  gInterpreter->SetClassAutoloading(1);
806  }
807 
808  // Set ROOT parameters.
809  TTree::SetMaxTreeSize(kMaxLong64);
810  TH1::AddDirectory(kFALSE);
811  //G__SetCatchException(0);
812 
813  // Set custom streamers
815 
816  // Load the library containing dictionaries for std:: classes, if not already loaded.
817  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
818  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
819  }
820 
821  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
822  if(debugLevel >0) {
823  gDebug = debugLevel;
824  }
825 
826  // Enable Root implicit multi-threading
827  bool imt = pset.getUntrackedParameter<bool>("EnableIMT");
828  if (imt) ROOT::EnableImplicitMT();
829  }
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:46
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:59
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
std::shared_ptr< const void > sigIllHandler_
std::shared_ptr< const void > sigTermHandler_
static std::vector< std::array< char, moduleBufferSize > > moduleListBuffers_
bool hasDictionary(std::type_info const &)
edm::service::InitRootHandlers::~InitRootHandlers ( )
virtual

Definition at line 831 of file InitRootHandlers.cc.

References f, and MuonAssociatorByHits_cfi::obj.

831  {
832  // close all open ROOT files
833  TIter iter(gROOT->GetListOfFiles());
834  TObject *obj = nullptr;
835  while(nullptr != (obj = iter.Next())) {
836  TFile* f = dynamic_cast<TFile*>(obj);
837  if(f) {
838  // We get a new iterator each time,
839  // because closing a file can invalidate the iterator
840  f->Close();
841  iter = TIter(gROOT->GetListOfFiles());
842  }
843  }
844  }
double f[11][100]

Member Function Documentation

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

Definition at line 895 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

896  {
897  if(helperThread_) {
898  //Another InitRootHandlers was initialized in this job, possibly
899  // because multiple EventProcessors are being used.
900  //In that case, we are already all setup
901  return;
902  }
903  if (snprintf(pidString_, pidStringLength_-1, "gdb -quiet -p %d 2>&1 <<EOF |\n"
904  "set width 0\n"
905  "set height 0\n"
906  "set pagination no\n"
907  "thread apply all bt\n"
908  "EOF\n"
909  "/bin/sed -n -e 's/^\\((gdb) \\)*//' -e '/^#/p' -e '/^Thread/p'", getpid()) >= pidStringLength_)
910  {
911  std::ostringstream sstr;
912  sstr << "Unable to pre-allocate stacktrace handler information";
913  edm::Exception except(edm::errors::OtherCMS, sstr.str());
914  throw except;
915  }
916 
917  // These are initialized to -1; harmless to close an invalid FD.
918  // If this is called post-fork, we don't want to be communicating on
919  // these FDs as they are used internally by the parent.
920  close(childToParent_[0]);
921  close(childToParent_[1]);
922  childToParent_[0] = -1; childToParent_[1] = -1;
923  close(parentToChild_[0]);
924  close(parentToChild_[1]);
925  parentToChild_[0] = -1; parentToChild_[1] = -1;
926 
927  if (-1 == pipe2(childToParent_, O_CLOEXEC))
928  {
929  std::ostringstream sstr;
930  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
931  edm::Exception except(edm::errors::OtherCMS, sstr.str());
932  throw except;
933  }
934 
935  if (-1 == pipe2(parentToChild_, O_CLOEXEC))
936  {
937  close(childToParent_[0]); close(childToParent_[1]);
938  childToParent_[0] = -1; childToParent_[1] = -1;
939  std::ostringstream sstr;
940  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
941  edm::Exception except(edm::errors::OtherCMS, sstr.str());
942  throw except;
943  }
944 
945  helperThread_.reset(new std::thread(stacktraceHelperThread));
946  helperThread_->detach();
947  }
static char pidString_[pidStringLength_]
static std::unique_ptr< std::thread > helperThread_
void edm::service::InitRootHandlers::enableWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 885 of file InitRootHandlers.cc.

885  {
886  s_ignoreWarnings =false;
887  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 857 of file InitRootHandlers.cc.

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

857  {
859  desc.setComment("Centralized interface to ROOT.");
860  desc.addUntracked<bool>("UnloadRootSigHandler", false)
861  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
862  desc.addUntracked<bool>("ResetRootErrHandler", true)
863  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
864  desc.addUntracked<bool>("AutoLibraryLoader", true)
865  ->setComment("If True, enables automatic loading of data dictionaries.");
866  desc.addUntracked<bool>("LoadAllDictionaries",false)
867  ->setComment("If True, loads all ROOT dictionaries.");
868  desc.addUntracked<bool>("EnableIMT",false)
869  ->setComment("If True, calls ROOT::EnableImplicitMT().");
870  desc.addUntracked<bool>("AbortOnSignal",true)
871  ->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.");
872  desc.addUntracked<int>("DebugLevel",0)
873  ->setComment("Sets ROOT's gDebug value.");
874  desc.addUntracked<int>("StackTracePauseTime", 300)
875  ->setComment("Seconds to pause other threads during stack trace.");
876  descriptions.add("InitRootHandlers", desc);
877  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 880 of file InitRootHandlers.cc.

References pstackArgv_.

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

880  {
881  return pstackArgv_;
882  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 890 of file InitRootHandlers.cc.

890  {
891  s_ignoreWarnings = true;
892  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 655 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

656  {
657  int result = full_write(parentToChild_[1], "1");
658  if (result < 0)
659  {
660  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
661  full_cerr_write(strerror(-result));
662  full_cerr_write("\n");
663  return;
664  }
665  char buf[2]; buf[1] = '\0';
666  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
667  {
668  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
669  if (result == -ETIMEDOUT)
670  {
671  full_cerr_write("timed out waiting for GDB to complete.");
672  }
673  else
674  {
675  full_cerr_write(strerror(-result));
676  }
677  full_cerr_write("\n");
678  return;
679  }
680  }
void edm::service::InitRootHandlers::stacktraceHelperThread ( )
staticprivate

Definition at line 603 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

604  {
605  int toParent = childToParent_[1];
606  int fromParent = parentToChild_[0];
607  char buf[2]; buf[1] = '\0';
608 
609  while(true)
610  {
611  int result = full_read(fromParent, buf, 1);
612  if (result < 0)
613  {
614  // To avoid a deadlock (this function is NOT re-entrant), reset signals
615  // We never set them back to the CMSSW handler because we assume the parent
616  // thread will abort for us.
617  set_default_signals();
618  close(toParent);
619  full_cerr_write("\n\nTraceback helper thread failed to read from parent: ");
620  full_cerr_write(strerror(-result));
621  full_cerr_write("\n");
622  ::abort();
623  }
624  if (buf[0] == '1')
625  {
626  set_default_signals();
628  full_write(toParent, buf);
629  }
630  else if (buf[0] == '2')
631  {
632  // We have just finished forking. Reload the file descriptors for thread
633  // communication.
634  close(toParent);
635  close(fromParent);
636  toParent = childToParent_[1];
637  fromParent = parentToChild_[0];
638  }
639  else if (buf[0] == '3')
640  {
641  break;
642  }
643  else
644  {
645  set_default_signals();
646  close(toParent);
647  full_cerr_write("\n\nTraceback helper thread got unknown command from parent: ");
648  full_cerr_write(buf);
649  full_cerr_write("\n");
650  ::abort();
651  }
652  }
653  }
static void cmssw_stacktrace_fork()
static int edm::service::InitRootHandlers::stackTracePause ( )
inlinestatic

Definition at line 97 of file InitRootHandlers.cc.

References stackTracePause_.

static const ThreadTracker::Container_type& edm::service::InitRootHandlers::threadIDs ( )
inlinestatic
void edm::service::InitRootHandlers::willBeUsingThreads ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 846 of file InitRootHandlers.cc.

846  {
847  //Tell Root we want to be multi-threaded
848  ROOT::EnableThreadSafety();
849 
850  //When threading, also have to keep ROOT from logging all TObjects into a list
851  TObject::SetObjectStat(false);
852 
853  //Have to avoid having Streamers modify themselves after they have been used
854  TVirtualStreamerInfo::Optimize(false);
855  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 716 of file InitRootHandlers.cc.

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

717  {
719  // NOTE: this is NOT async-signal-safe at CERN's lxplus service.
720  // CERN uses LD_PRELOAD to replace execv with a function from libsnoopy which
721  // calls dlsym.
722 #ifdef __linux__
723  syscall(SYS_execve, "/bin/sh", argv, __environ);
724 #else
725  execv("/bin/sh", argv);
726 #endif
727  ::abort();
728  return 1;
729  }
static char *const * getPstackArgv()

Member Data Documentation

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

Definition at line 122 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 114 of file InitRootHandlers.cc.

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

std::atomic< std::size_t > edm::service::InitRootHandlers::doneModules_
static

Definition at line 100 of file InitRootHandlers.cc.

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

Definition at line 115 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 121 of file InitRootHandlers.cc.

std::vector< std::array< char, moduleBufferSize > > edm::service::InitRootHandlers::moduleListBuffers_
static

Definition at line 99 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

std::atomic< std::size_t > edm::service::InitRootHandlers::nextModule_
static

Definition at line 100 of file InitRootHandlers.cc.

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

Definition at line 113 of file InitRootHandlers.cc.

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

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

Definition at line 111 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 110 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 112 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

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

Definition at line 120 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 123 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 125 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 124 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 126 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

int edm::service::InitRootHandlers::stackTracePause_ = 300
staticprivate

Definition at line 117 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and stackTracePause().

InitRootHandlers::ThreadTracker edm::service::InitRootHandlers::threadTracker_
staticprivate

Definition at line 116 of file InitRootHandlers.cc.

Referenced by threadIDs().

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

Definition at line 119 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().