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 ()
 
void cachePidInfoHandler (unsigned int, unsigned int)
 
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 745 of file InitRootHandlers.cc.

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

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

References f, and MuonAssociatorByHits_cfi::obj.

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

Member Function Documentation

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

Definition at line 897 of file InitRootHandlers.cc.

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

Referenced by cachePidInfoHandler(), and InitRootHandlers().

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

Definition at line 107 of file InitRootHandlers.cc.

References cachePidInfo(), helperThread_, and stacktraceHelperThread().

Referenced by InitRootHandlers().

107  {
108  //this is called only on a fork, so the thread doesn't
109  // actually exist anymore
110  helperThread_.reset();
111  cachePidInfo();}
static std::unique_ptr< std::thread > helperThread_
void edm::service::InitRootHandlers::enableWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 887 of file InitRootHandlers.cc.

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

Definition at line 859 of file InitRootHandlers.cc.

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

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

Definition at line 882 of file InitRootHandlers.cc.

References pstackArgv_.

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

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

Implements edm::RootHandlers.

Definition at line 892 of file InitRootHandlers.cc.

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

Definition at line 656 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

Definition at line 604 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo(), and cachePidInfoHandler().

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

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

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 717 of file InitRootHandlers.cc.

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

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

Member Data Documentation

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

Definition at line 127 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 119 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 120 of file InitRootHandlers.cc.

Referenced by cachePidInfo(), and cachePidInfoHandler().

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

Definition at line 126 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 118 of file InitRootHandlers.cc.

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

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

Definition at line 116 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 115 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 117 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

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

Definition at line 125 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 128 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 130 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 129 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 131 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 122 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and stackTracePause().

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

Definition at line 121 of file InitRootHandlers.cc.

Referenced by threadIDs().

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

Definition at line 124 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().