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

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  installCustomHandler(SIGABRT,sig_dostack_then_abort);
818  sigAbrtHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
819  signal(SIGABRT,SIG_DFL); // release SIGABRT to default
820  });
821  }
822 
823  iReg.watchPreallocate([](edm::service::SystemBounds const& iBounds){
824  if (iBounds.maxNumberOfThreads() > moduleListBuffers_.size()) {
825  moduleListBuffers_.resize(iBounds.maxNumberOfThreads());
826  }
827  });
828 
829  if(resetErrHandler_) {
830 
831  // Replace the Root error handler with one that uses the MessageLogger
832  SetErrorHandler(RootErrorHandler);
833  }
834 
835  // Enable automatic Root library loading.
836  if(autoLibraryLoader_) {
837  gInterpreter->SetClassAutoloading(1);
838  }
839 
840  // Set ROOT parameters.
841  TTree::SetMaxTreeSize(kMaxLong64);
842  TH1::AddDirectory(kFALSE);
843  //G__SetCatchException(0);
844 
845  // Set custom streamers
847 
848  // Load the library containing dictionaries for std:: classes, if not already loaded.
849  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
850  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
851  }
852 
853  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
854  if(debugLevel >0) {
855  gDebug = debugLevel;
856  }
857 
858  // Enable Root implicit multi-threading
859  bool imt = pset.getUntrackedParameter<bool>("EnableIMT");
860  if (imt && not ROOT::IsImplicitMTEnabled()) {
861  ROOT::EnableImplicitMT();
862  }
863  }
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 865 of file InitRootHandlers.cc.

References f, and GetRecoTauVFromDQM_MC_cff::obj.

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

Member Function Documentation

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

Definition at line 929 of file InitRootHandlers.cc.

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

Referenced by InitRootHandlers().

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

Implements edm::RootHandlers.

Definition at line 919 of file InitRootHandlers.cc.

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

Definition at line 891 of file InitRootHandlers.cc.

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

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

Definition at line 914 of file InitRootHandlers.cc.

References pstackArgv_.

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

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

Implements edm::RootHandlers.

Definition at line 924 of file InitRootHandlers.cc.

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

Definition at line 681 of file InitRootHandlers.cc.

References childToParent_, parentToChild_, and mps_fire::result.

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

Definition at line 629 of file InitRootHandlers.cc.

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

Referenced by cachePidInfo().

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

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

Friends And Related Function Documentation

int cmssw_stacktrace ( void *  )
friend

Definition at line 742 of file InitRootHandlers.cc.

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

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