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

787  : RootHandlers(),
788  unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler")),
789  resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler")),
790  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
791  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool> ("AutoLibraryLoader"))
792  {
793  stackTracePause_ = pset.getUntrackedParameter<int> ("StackTracePauseTime");
794 
795  if(unloadSigHandler_) {
796  // Deactivate all the Root signal handlers and restore the system defaults
797  gSystem->ResetSignal(kSigChild);
798  gSystem->ResetSignal(kSigBus);
799  gSystem->ResetSignal(kSigSegmentationViolation);
800  gSystem->ResetSignal(kSigIllegalInstruction);
801  gSystem->ResetSignal(kSigSystem);
802  gSystem->ResetSignal(kSigPipe);
803  gSystem->ResetSignal(kSigAlarm);
804  gSystem->ResetSignal(kSigUrgent);
805  gSystem->ResetSignal(kSigFloatingException);
806  gSystem->ResetSignal(kSigWindowChanged);
807  } else if(pset.getUntrackedParameter<bool>("AbortOnSignal")){
808  cachePidInfo();
809 
810  //NOTE: ROOT can also be told to abort on these kinds of problems BUT
811  // it requires an TApplication to be instantiated which causes problems
812  gSystem->ResetSignal(kSigBus);
813  gSystem->ResetSignal(kSigSegmentationViolation);
814  gSystem->ResetSignal(kSigIllegalInstruction);
815  installCustomHandler(SIGBUS,sig_dostack_then_abort);
816  sigBusHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
817  installCustomHandler(SIGBUS,sig_abort);
818  });
819  installCustomHandler(SIGSEGV,sig_dostack_then_abort);
820  sigSegvHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
821  installCustomHandler(SIGSEGV,sig_abort);
822  });
823  installCustomHandler(SIGILL,sig_dostack_then_abort);
824  sigIllHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
825  installCustomHandler(SIGILL,sig_abort);
826  });
827  installCustomHandler(SIGTERM,sig_dostack_then_abort);
828  sigTermHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
829  installCustomHandler(SIGTERM,sig_abort);
830  });
831  installCustomHandler(SIGABRT,sig_dostack_then_abort);
832  sigAbrtHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
833  signal(SIGABRT,SIG_DFL); // release SIGABRT to default
834  });
835  }
836 
837  iReg.watchPreallocate([](edm::service::SystemBounds const& iBounds){
838  if (iBounds.maxNumberOfThreads() > moduleListBuffers_.size()) {
839  moduleListBuffers_.resize(iBounds.maxNumberOfThreads());
840  }
841  });
842 
843  if(resetErrHandler_) {
844 
845  // Replace the Root error handler with one that uses the MessageLogger
846  SetErrorHandler(RootErrorHandler);
847  }
848 
849  // Enable automatic Root library loading.
850  if(autoLibraryLoader_) {
851  gInterpreter->SetClassAutoloading(1);
852  }
853 
854  // Set ROOT parameters.
855  TTree::SetMaxTreeSize(kMaxLong64);
856  TH1::AddDirectory(kFALSE);
857  //G__SetCatchException(0);
858 
859  // Set custom streamers
861 
862  // Load the library containing dictionaries for std:: classes, if not already loaded.
863  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
864  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
865  }
866 
867  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
868  if(debugLevel >0) {
869  gDebug = debugLevel;
870  }
871 
872  // Enable Root implicit multi-threading
873  bool imt = pset.getUntrackedParameter<bool>("EnableIMT");
874  if (imt && not ROOT::IsImplicitMTEnabled()) {
875  ROOT::EnableImplicitMT();
876  }
877  }
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:46
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:82
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 879 of file InitRootHandlers.cc.

References f, and GetRecoTauVFromDQM_MC_cff::obj.

879  {
880  // close all open ROOT files
881  TIter iter(gROOT->GetListOfFiles());
882  TObject *obj = nullptr;
883  while(nullptr != (obj = iter.Next())) {
884  TFile* f = dynamic_cast<TFile*>(obj);
885  if(f) {
886  // We get a new iterator each time,
887  // because closing a file can invalidate the iterator
888  f->Close();
889  iter = TIter(gROOT->GetListOfFiles());
890  }
891  }
892  }
double f[11][100]

Member Function Documentation

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

Definition at line 943 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

944  {
945  if(helperThread_) {
946  //Another InitRootHandlers was initialized in this job, possibly
947  // because multiple EventProcessors are being used.
948  //In that case, we are already all setup
949  return;
950  }
951  if (snprintf(pidString_, pidStringLength_-1, "gdb -quiet -p %d 2>&1 <<EOF |\n"
952  "set width 0\n"
953  "set height 0\n"
954  "set pagination no\n"
955  "thread apply all bt\n"
956  "EOF\n"
957  "/bin/sed -n -e 's/^\\((gdb) \\)*//' -e '/^#/p' -e '/^Thread/p'", getpid()) >= pidStringLength_)
958  {
959  std::ostringstream sstr;
960  sstr << "Unable to pre-allocate stacktrace handler information";
961  edm::Exception except(edm::errors::OtherCMS, sstr.str());
962  throw except;
963  }
964 
965  // These are initialized to -1; harmless to close an invalid FD.
966  // If this is called post-fork, we don't want to be communicating on
967  // these FDs as they are used internally by the parent.
968  close(childToParent_[0]);
969  close(childToParent_[1]);
970  childToParent_[0] = -1; childToParent_[1] = -1;
971  close(parentToChild_[0]);
972  close(parentToChild_[1]);
973  parentToChild_[0] = -1; parentToChild_[1] = -1;
974 
975  if (-1 == pipe2(childToParent_, O_CLOEXEC))
976  {
977  std::ostringstream sstr;
978  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
979  edm::Exception except(edm::errors::OtherCMS, sstr.str());
980  throw except;
981  }
982 
983  if (-1 == pipe2(parentToChild_, O_CLOEXEC))
984  {
985  close(childToParent_[0]); close(childToParent_[1]);
986  childToParent_[0] = -1; childToParent_[1] = -1;
987  std::ostringstream sstr;
988  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
989  edm::Exception except(edm::errors::OtherCMS, sstr.str());
990  throw except;
991  }
992 
993  helperThread_.reset(new std::thread(stacktraceHelperThread));
994  helperThread_->detach();
995  }
static char pidString_[pidStringLength_]
static std::unique_ptr< std::thread > helperThread_
void edm::service::InitRootHandlers::enableWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 933 of file InitRootHandlers.cc.

References edm::RootHandlers::kInfo.

void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 905 of file InitRootHandlers.cc.

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

905  {
907  desc.setComment("Centralized interface to ROOT.");
908  desc.addUntracked<bool>("UnloadRootSigHandler", false)
909  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
910  desc.addUntracked<bool>("ResetRootErrHandler", true)
911  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
912  desc.addUntracked<bool>("AutoLibraryLoader", true)
913  ->setComment("If True, enables automatic loading of data dictionaries.");
914  desc.addUntracked<bool>("LoadAllDictionaries",false)
915  ->setComment("If True, loads all ROOT dictionaries.");
916  desc.addUntracked<bool>("EnableIMT",true)
917  ->setComment("If True, calls ROOT::EnableImplicitMT().");
918  desc.addUntracked<bool>("AbortOnSignal",true)
919  ->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.");
920  desc.addUntracked<int>("DebugLevel",0)
921  ->setComment("Sets ROOT's gDebug value.");
922  desc.addUntracked<int>("StackTracePauseTime", 300)
923  ->setComment("Seconds to pause other threads during stack trace.");
924  descriptions.add("InitRootHandlers", desc);
925  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 928 of file InitRootHandlers.cc.

References pstackArgv_.

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

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

Implements edm::RootHandlers.

Definition at line 938 of file InitRootHandlers.cc.

References hcalDigis_cfi::level.

938  {
939  s_ignoreWarnings = level;
940  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 695 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

696  {
697  int result = full_write(parentToChild_[1], "1");
698  if (result < 0)
699  {
700  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
701  full_cerr_write(strerror(-result));
702  full_cerr_write("\n");
703  return;
704  }
705  char buf[2]; buf[1] = '\0';
706  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
707  {
708  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
709  if (result == -ETIMEDOUT)
710  {
711  full_cerr_write("timed out waiting for GDB to complete.");
712  }
713  else
714  {
715  full_cerr_write(strerror(-result));
716  }
717  full_cerr_write("\n");
718  return;
719  }
720  }
void edm::service::InitRootHandlers::stacktraceHelperThread ( )
staticprivate

Definition at line 643 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

644  {
645  int toParent = childToParent_[1];
646  int fromParent = parentToChild_[0];
647  char buf[2]; buf[1] = '\0';
648 
649  while(true)
650  {
651  int result = full_read(fromParent, buf, 1);
652  if (result < 0)
653  {
654  // To avoid a deadlock (this function is NOT re-entrant), reset signals
655  // We never set them back to the CMSSW handler because we assume the parent
656  // thread will abort for us.
657  set_default_signals();
658  close(toParent);
659  full_cerr_write("\n\nTraceback helper thread failed to read from parent: ");
660  full_cerr_write(strerror(-result));
661  full_cerr_write("\n");
662  ::abort();
663  }
664  if (buf[0] == '1')
665  {
666  set_default_signals();
668  full_write(toParent, buf);
669  }
670  else if (buf[0] == '2')
671  {
672  // We have just finished forking. Reload the file descriptors for thread
673  // communication.
674  close(toParent);
675  close(fromParent);
676  toParent = childToParent_[1];
677  fromParent = parentToChild_[0];
678  }
679  else if (buf[0] == '3')
680  {
681  break;
682  }
683  else
684  {
685  set_default_signals();
686  close(toParent);
687  full_cerr_write("\n\nTraceback helper thread got unknown command from parent: ");
688  full_cerr_write(buf);
689  full_cerr_write("\n");
690  ::abort();
691  }
692  }
693  }
static void cmssw_stacktrace_fork()
static int edm::service::InitRootHandlers::stackTracePause ( )
inlinestatic

Definition at line 101 of file InitRootHandlers.cc.

References stackTracePause_.

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

101 { return stackTracePause_; }
static const ThreadTracker::Container_type& edm::service::InitRootHandlers::threadIDs ( )
inlinestatic
void edm::service::InitRootHandlers::willBeUsingThreads ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 894 of file InitRootHandlers.cc.

894  {
895  //Tell Root we want to be multi-threaded
896  ROOT::EnableThreadSafety();
897 
898  //When threading, also have to keep ROOT from logging all TObjects into a list
899  TObject::SetObjectStat(false);
900 
901  //Have to avoid having Streamers modify themselves after they have been used
902  TVirtualStreamerInfo::Optimize(false);
903  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 756 of file InitRootHandlers.cc.

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

757  {
758  set_default_signals();
759 
761  // NOTE: this is NOT async-signal-safe at CERN's lxplus service.
762  // CERN uses LD_PRELOAD to replace execv with a function from libsnoopy which
763  // calls dlsym.
764 #ifdef __linux__
765  syscall(SYS_execve, "/bin/sh", argv, __environ);
766 #else
767  execv("/bin/sh", argv);
768 #endif
769  ::abort();
770  return 1;
771  }
static char *const * getPstackArgv()

Member Data Documentation

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

Definition at line 126 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 118 of file InitRootHandlers.cc.

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

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

Definition at line 104 of file InitRootHandlers.cc.

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

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

Definition at line 119 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 125 of file InitRootHandlers.cc.

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

Definition at line 103 of file InitRootHandlers.cc.

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

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

Definition at line 104 of file InitRootHandlers.cc.

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

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

Definition at line 117 of file InitRootHandlers.cc.

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

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

Definition at line 115 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 114 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 116 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

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

Definition at line 124 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 131 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 127 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 129 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 128 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 130 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 121 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and stackTracePause().

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

Definition at line 120 of file InitRootHandlers.cc.

Referenced by threadIDs().

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

Definition at line 123 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().