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

Constructor & Destructor Documentation

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

Definition at line 772 of file InitRootHandlers.cc.

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

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

References f, and MuonAssociatorByHits_cfi::obj.

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

Member Function Documentation

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

Definition at line 941 of file InitRootHandlers.cc.

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

Referenced by cachePidInfoHandler(), and InitRootHandlers().

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

Definition at line 108 of file InitRootHandlers.cc.

References cachePidInfo(), and stacktraceHelperThread().

Referenced by InitRootHandlers().

void edm::service::InitRootHandlers::enableWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 931 of file InitRootHandlers.cc.

931  {
932  s_ignoreWarnings =false;
933  }
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>("AbortOnSignal",true)
917  ->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.");
918  desc.addUntracked<int>("DebugLevel",0)
919  ->setComment("Sets ROOT's gDebug value.");
920  desc.addUntracked<int>("StackTracePauseTime", 300)
921  ->setComment("Seconds to pause other threads during stack trace.");
922  descriptions.add("InitRootHandlers", desc);
923  }
char *const * edm::service::InitRootHandlers::getPstackArgv ( )
staticprivate

Definition at line 926 of file InitRootHandlers.cc.

References pstackArgv_.

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

926  {
927  return pstackArgv_;
928  }
static char *const pstackArgv_[]
void edm::service::InitRootHandlers::ignoreWarnings_ ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 936 of file InitRootHandlers.cc.

936  {
937  s_ignoreWarnings = true;
938  }
void edm::service::InitRootHandlers::initializeThisThreadForUse ( )
overrideprivatevirtual

Implements edm::RootHandlers.

Definition at line 901 of file InitRootHandlers.cc.

901  {
902  localInitializeThisThreadForUse();
903  }
void edm::service::InitRootHandlers::stacktraceFromThread ( )
static

Definition at line 653 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

Definition at line 601 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo(), and cachePidInfoHandler().

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

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

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 714 of file InitRootHandlers.cc.

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

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

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