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 > 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 *)
 

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

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

References f, and GetRecoTauVFromDQM_MC_cff::obj.

866  {
867  // close all open ROOT files
868  TIter iter(gROOT->GetListOfFiles());
869  TObject *obj = nullptr;
870  while(nullptr != (obj = iter.Next())) {
871  TFile* f = dynamic_cast<TFile*>(obj);
872  if(f) {
873  // We get a new iterator each time,
874  // because closing a file can invalidate the iterator
875  f->Close();
876  iter = TIter(gROOT->GetListOfFiles());
877  }
878  }
879  }
double f[11][100]

Member Function Documentation

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

Definition at line 930 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

Implements edm::RootHandlers.

Definition at line 920 of file InitRootHandlers.cc.

920  {
921  s_ignoreWarnings =false;
922  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 892 of file InitRootHandlers.cc.

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

892  {
894  desc.setComment("Centralized interface to ROOT.");
895  desc.addUntracked<bool>("UnloadRootSigHandler", false)
896  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
897  desc.addUntracked<bool>("ResetRootErrHandler", true)
898  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
899  desc.addUntracked<bool>("AutoLibraryLoader", true)
900  ->setComment("If True, enables automatic loading of data dictionaries.");
901  desc.addUntracked<bool>("LoadAllDictionaries",false)
902  ->setComment("If True, loads all ROOT dictionaries.");
903  desc.addUntracked<bool>("EnableIMT",true)
904  ->setComment("If True, calls ROOT::EnableImplicitMT().");
905  desc.addUntracked<bool>("AbortOnSignal",true)
906  ->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.");
907  desc.addUntracked<int>("DebugLevel",0)
908  ->setComment("Sets ROOT's gDebug value.");
909  desc.addUntracked<int>("StackTracePauseTime", 300)
910  ->setComment("Seconds to pause other threads during stack trace.");
911  descriptions.add("InitRootHandlers", desc);
912  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 915 of file InitRootHandlers.cc.

References pstackArgv_.

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

915  {
916  return pstackArgv_;
917  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 925 of file InitRootHandlers.cc.

925  {
926  s_ignoreWarnings = true;
927  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 682 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

683  {
684  int result = full_write(parentToChild_[1], "1");
685  if (result < 0)
686  {
687  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
688  full_cerr_write(strerror(-result));
689  full_cerr_write("\n");
690  return;
691  }
692  char buf[2]; buf[1] = '\0';
693  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
694  {
695  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
696  if (result == -ETIMEDOUT)
697  {
698  full_cerr_write("timed out waiting for GDB to complete.");
699  }
700  else
701  {
702  full_cerr_write(strerror(-result));
703  }
704  full_cerr_write("\n");
705  return;
706  }
707  }
void edm::service::InitRootHandlers::stacktraceHelperThread ( )
staticprivate

Definition at line 630 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

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

881  {
882  //Tell Root we want to be multi-threaded
883  ROOT::EnableThreadSafety();
884 
885  //When threading, also have to keep ROOT from logging all TObjects into a list
886  TObject::SetObjectStat(false);
887 
888  //Have to avoid having Streamers modify themselves after they have been used
889  TVirtualStreamerInfo::Optimize(false);
890  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 743 of file InitRootHandlers.cc.

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

744  {
745  set_default_signals();
746 
748  // NOTE: this is NOT async-signal-safe at CERN's lxplus service.
749  // CERN uses LD_PRELOAD to replace execv with a function from libsnoopy which
750  // calls dlsym.
751 #ifdef __linux__
752  syscall(SYS_execve, "/bin/sh", argv, __environ);
753 #else
754  execv("/bin/sh", argv);
755 #endif
756  ::abort();
757  return 1;
758  }
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::sigAbrtHandler_
private

Definition at line 127 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().