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 747 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().

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

References f, and haddnano::obj.

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

Member Function Documentation

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

Definition at line 884 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

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

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

Definition at line 878 of file InitRootHandlers.cc.

References pstackArgv_.

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

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

Implements edm::RootHandlers.

Definition at line 882 of file InitRootHandlers.cc.

References hcalDigis_cfi::level.

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

Definition at line 666 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

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

Definition at line 623 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

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

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

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 719 of file InitRootHandlers.cc.

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

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