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, SeverityLevel level=SeverityLevel::kWarning)
 
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_ (edm::RootHandlers::SeverityLevel level) 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 > sigAbrtHandler_
 
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 *)
 

Additional Inherited Members

- Public Types inherited from edm::RootHandlers
enum  SeverityLevel {
  SeverityLevel::kInfo, SeverityLevel::kWarning, SeverityLevel::kError, SeverityLevel::kSysError,
  SeverityLevel::kFatal
}
 

Detailed Description

Definition at line 68 of file InitRootHandlers.cc.

Constructor & Destructor Documentation

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

Definition at line 746 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::setRefCoreStreamerInTClass(), sigAbrtHandler_, sigBusHandler_, sigIllHandler_, sigSegvHandler_, sigTermHandler_, stackTracePause_, unloadSigHandler_, and edm::ActivityRegistry::watchPreallocate().

747  : RootHandlers(),
748  unloadSigHandler_(pset.getUntrackedParameter<bool>("UnloadRootSigHandler")),
749  resetErrHandler_(pset.getUntrackedParameter<bool>("ResetRootErrHandler")),
750  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
751  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool>("AutoLibraryLoader")) {
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*) { installCustomHandler(SIGBUS, sig_abort); });
776  installCustomHandler(SIGSEGV, sig_dostack_then_abort);
777  sigSegvHandler_ = std::shared_ptr<const void>(nullptr, [](void*) { installCustomHandler(SIGSEGV, sig_abort); });
778  installCustomHandler(SIGILL, sig_dostack_then_abort);
779  sigIllHandler_ = std::shared_ptr<const void>(nullptr, [](void*) { installCustomHandler(SIGILL, sig_abort); });
780  installCustomHandler(SIGTERM, sig_dostack_then_abort);
781  sigTermHandler_ = std::shared_ptr<const void>(nullptr, [](void*) { installCustomHandler(SIGTERM, sig_abort); });
782  installCustomHandler(SIGABRT, sig_dostack_then_abort);
783  sigAbrtHandler_ = std::shared_ptr<const void>(nullptr, [](void*) {
784  signal(SIGABRT, SIG_DFL); // release SIGABRT to default
785  });
786  }
787 
788  iReg.watchPreallocate([](edm::service::SystemBounds const& iBounds) {
789  if (iBounds.maxNumberOfThreads() > moduleListBuffers_.size()) {
790  moduleListBuffers_.resize(iBounds.maxNumberOfThreads());
791  }
792  });
793 
794  if (resetErrHandler_) {
795  // Replace the Root error handler with one that uses the MessageLogger
796  SetErrorHandler(RootErrorHandler);
797  }
798 
799  // Enable automatic Root library loading.
800  if (autoLibraryLoader_) {
801  gInterpreter->SetClassAutoloading(1);
802  }
803 
804  // Set ROOT parameters.
805  TTree::SetMaxTreeSize(kMaxLong64);
806  TH1::AddDirectory(kFALSE);
807  //G__SetCatchException(0);
808 
809  // Set custom streamers
811 
812  // Load the library containing dictionaries for std:: classes, if not already loaded.
813  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int>>))) {
814  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
815  }
816 
817  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
818  if (debugLevel > 0) {
819  gDebug = debugLevel;
820  }
821 
822  // Enable Root implicit multi-threading
823  bool imt = pset.getUntrackedParameter<bool>("EnableIMT");
824  if (imt && not ROOT::IsImplicitMTEnabled()) {
825  ROOT::EnableImplicitMT();
826  }
827  }
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:38
void setRefCoreStreamerInTClass()
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:74
std::shared_ptr< const void > sigAbrtHandler_
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 829 of file InitRootHandlers.cc.

References f, and hgcalPlots::obj.

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

Member Function Documentation

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

Definition at line 883 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

Definition at line 855 of file InitRootHandlers.cc.

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

855  {
857  desc.setComment("Centralized interface to ROOT.");
858  desc.addUntracked<bool>("UnloadRootSigHandler", false)
859  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
860  desc.addUntracked<bool>("ResetRootErrHandler", true)
861  ->setComment(
862  "If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
863  desc.addUntracked<bool>("AutoLibraryLoader", true)
864  ->setComment("If True, enables automatic loading of data dictionaries.");
865  desc.addUntracked<bool>("LoadAllDictionaries", false)->setComment("If True, loads all ROOT dictionaries.");
866  desc.addUntracked<bool>("EnableIMT", true)->setComment("If True, calls ROOT::EnableImplicitMT().");
867  desc.addUntracked<bool>("AbortOnSignal", true)
868  ->setComment(
869  "If True, do an abort when a signal occurs that causes a crash. If False, ROOT will do an exit which "
870  "attempts to do a clean shutdown.");
871  desc.addUntracked<int>("DebugLevel", 0)->setComment("Sets ROOT's gDebug value.");
872  desc.addUntracked<int>("StackTracePauseTime", 300)
873  ->setComment("Seconds to pause other threads during stack trace.");
874  descriptions.add("InitRootHandlers", desc);
875  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 877 of file InitRootHandlers.cc.

References pstackArgv_.

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

877 { return pstackArgv_; }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( edm::RootHandlers::SeverityLevel  level)
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 881 of file InitRootHandlers.cc.

References hcalDigis_cfi::level.

881 { s_ignoreWarnings = level; }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 665 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

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

Definition at line 622 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

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

Definition at line 98 of file InitRootHandlers.cc.

References stackTracePause_.

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

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

Implements edm::RootHandlers.

Definition at line 844 of file InitRootHandlers.cc.

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

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 718 of file InitRootHandlers.cc.

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

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

Member Data Documentation

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

Definition at line 124 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 116 of file InitRootHandlers.cc.

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

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

Definition at line 101 of file InitRootHandlers.cc.

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

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

Definition at line 117 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 123 of file InitRootHandlers.cc.

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

Definition at line 100 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and edm::service::isProcessWideService().

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

Definition at line 101 of file InitRootHandlers.cc.

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

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

Definition at line 115 of file InitRootHandlers.cc.

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

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

Definition at line 113 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 112 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 114 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

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

Definition at line 122 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 129 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 125 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 127 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 126 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 128 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 119 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and stackTracePause().

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

Definition at line 118 of file InitRootHandlers.cc.

Referenced by threadIDs().

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

Definition at line 121 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().