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)
 
 ~InitRootHandlers () override
 
- 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 ()
 
void enableWarnings_ () override
 
void ignoreWarnings_ () override
 
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 751 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().

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

Definition at line 840 of file InitRootHandlers.cc.

References f, and GetRecoTauVFromDQM_MC_cff::obj.

840  {
841  // close all open ROOT files
842  TIter iter(gROOT->GetListOfFiles());
843  TObject *obj = nullptr;
844  while(nullptr != (obj = iter.Next())) {
845  TFile* f = dynamic_cast<TFile*>(obj);
846  if(f) {
847  // We get a new iterator each time,
848  // because closing a file can invalidate the iterator
849  f->Close();
850  iter = TIter(gROOT->GetListOfFiles());
851  }
852  }
853  }
double f[11][100]

Member Function Documentation

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

Definition at line 904 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

Implements edm::RootHandlers.

Definition at line 894 of file InitRootHandlers.cc.

894  {
895  s_ignoreWarnings =false;
896  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 866 of file InitRootHandlers.cc.

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

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

Definition at line 889 of file InitRootHandlers.cc.

References pstackArgv_.

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

889  {
890  return pstackArgv_;
891  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 899 of file InitRootHandlers.cc.

899  {
900  s_ignoreWarnings = true;
901  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 662 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

Definition at line 610 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

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

855  {
856  //Tell Root we want to be multi-threaded
857  ROOT::EnableThreadSafety();
858 
859  //When threading, also have to keep ROOT from logging all TObjects into a list
860  TObject::SetObjectStat(false);
861 
862  //Have to avoid having Streamers modify themselves after they have been used
863  TVirtualStreamerInfo::Optimize(false);
864  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 723 of file InitRootHandlers.cc.

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

724  {
726  // NOTE: this is NOT async-signal-safe at CERN's lxplus service.
727  // CERN uses LD_PRELOAD to replace execv with a function from libsnoopy which
728  // calls dlsym.
729 #ifdef __linux__
730  syscall(SYS_execve, "/bin/sh", argv, __environ);
731 #else
732  execv("/bin/sh", argv);
733 #endif
734  ::abort();
735  return 1;
736  }
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().