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 initializeThisThreadForUse () 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 65 of file InitRootHandlers.cc.

Constructor & Destructor Documentation

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

Definition at line 777 of file InitRootHandlers.cc.

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

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

References f, and MuonAssociatorByHits_cfi::obj.

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

Member Function Documentation

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

Definition at line 952 of file InitRootHandlers.cc.

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

Referenced by cachePidInfoHandler(), and InitRootHandlers().

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

Definition at line 109 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

Implements edm::RootHandlers.

Definition at line 942 of file InitRootHandlers.cc.

942  {
943  s_ignoreWarnings =false;
944  }
void edm::service::InitRootHandlers::fillDescriptions ( ConfigurationDescriptions descriptions)
static

Definition at line 914 of file InitRootHandlers.cc.

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

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

Definition at line 937 of file InitRootHandlers.cc.

References pstackArgv_.

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

937  {
938  return pstackArgv_;
939  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 947 of file InitRootHandlers.cc.

947  {
948  s_ignoreWarnings = true;
949  }
void edm::service::InitRootHandlers::initializeThisThreadForUse ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 910 of file InitRootHandlers.cc.

910  {
911  localInitializeThisThreadForUse();
912  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 658 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

Definition at line 606 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo(), and cachePidInfoHandler().

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

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

900  {
901  //Tell Root we want to be multi-threaded
902  TThread::Initialize();
903  //When threading, also have to keep ROOT from logging all TObjects into a list
904  TObject::SetObjectStat(false);
905 
906  //Have to avoid having Streamers modify themselves after they have been used
907  TVirtualStreamerInfo::Optimize(false);
908  }

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 719 of file InitRootHandlers.cc.

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

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 129 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 121 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.

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

Definition at line 122 of file InitRootHandlers.cc.

Referenced by cachePidInfo(), and cachePidInfoHandler().

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

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

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

Definition at line 101 of file InitRootHandlers.cc.

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

Definition at line 120 of file InitRootHandlers.cc.

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

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

Definition at line 118 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 117 of file InitRootHandlers.cc.

Referenced by cachePidInfo().

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

Definition at line 119 of file InitRootHandlers.cc.

Referenced by getPstackArgv().

bool edm::service::InitRootHandlers::resetErrHandler_
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 130 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 132 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 131 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 133 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().

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

Definition at line 124 of file InitRootHandlers.cc.

Referenced by InitRootHandlers(), and stackTracePause().

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

Definition at line 123 of file InitRootHandlers.cc.

Referenced by threadIDs().

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

Definition at line 126 of file InitRootHandlers.cc.

Referenced by InitRootHandlers().