CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
InitRootHandlers.cc
Go to the documentation of this file.
2 
14 
15 #include <thread>
16 #include <sys/wait.h>
17 #include <sstream>
18 #include <string.h>
19 #include <poll.h>
20 
21 // WORKAROUND: At CERN, execv is replaced with a non-async-signal safe
22 // version. This can break our stack trace printer. Avoid this by
23 // invoking the syscall directly.
24 #ifdef __linux__
25 #include <syscall.h>
26 #endif
27 
28 #include "TROOT.h"
29 #include "TError.h"
30 #include "TFile.h"
31 #include "TInterpreter.h"
32 #include "TH1.h"
33 #include "TSystem.h"
34 #include "TUnixSystem.h"
35 #include "TTree.h"
36 #include "TVirtualStreamerInfo.h"
37 
38 #include "TThread.h"
39 #include "TClassTable.h"
40 
41 namespace edm {
42  namespace service {
43  int cmssw_stacktrace(void *);
44  }
45 }
46 
47 namespace {
48  enum class SeverityLevel {
49  kInfo,
50  kWarning,
51  kError,
52  kSysError,
53  kFatal
54  };
55 
56  static thread_local bool s_ignoreWarnings = false;
57 
58  static bool s_ignoreEverything = false;
59 
60  void RootErrorHandlerImpl(int level, char const* location, char const* message) {
61 
62  bool die = false;
63 
64  // Translate ROOT severity level to MessageLogger severity level
65 
66  SeverityLevel el_severity = SeverityLevel::kInfo;
67 
68  if (level >= kFatal) {
69  el_severity = SeverityLevel::kFatal;
70  } else if (level >= kSysError) {
71  el_severity = SeverityLevel::kSysError;
72  } else if (level >= kError) {
73  el_severity = SeverityLevel::kError;
74  } else if (level >= kWarning) {
75  el_severity = s_ignoreWarnings ? SeverityLevel::kInfo : SeverityLevel::kWarning;
76  }
77 
78  if(s_ignoreEverything) {
79  el_severity = SeverityLevel::kInfo;
80  }
81 
82  // Adapt C-strings to std::strings
83  // Arrange to report the error location as furnished by Root
84 
85  std::string el_location = "@SUB=?";
86  if (location != 0) el_location = std::string("@SUB=")+std::string(location);
87 
88  std::string el_message = "?";
89  if (message != 0) el_message = message;
90 
91  // Try to create a meaningful id string using knowledge of ROOT error messages
92  //
93  // id == "ROOT-ClassName" where ClassName is the affected class
94  // else "ROOT/ClassName" where ClassName is the error-declaring class
95  // else "ROOT"
96 
97  std::string el_identifier = "ROOT";
98 
99  std::string precursor("class ");
100  size_t index1 = el_message.find(precursor);
101  if (index1 != std::string::npos) {
102  size_t index2 = index1 + precursor.length();
103  size_t index3 = el_message.find_first_of(" :", index2);
104  if (index3 != std::string::npos) {
105  size_t substrlen = index3-index2;
106  el_identifier += "-";
107  el_identifier += el_message.substr(index2,substrlen);
108  }
109  } else {
110  index1 = el_location.find("::");
111  if (index1 != std::string::npos) {
112  el_identifier += "/";
113  el_identifier += el_location.substr(0, index1);
114  }
115  }
116 
117  // Intercept some messages and upgrade the severity
118 
119  if ((el_location.find("TBranchElement::Fill") != std::string::npos)
120  && (el_message.find("fill branch") != std::string::npos)
121  && (el_message.find("address") != std::string::npos)
122  && (el_message.find("not set") != std::string::npos)) {
123  el_severity = SeverityLevel::kFatal;
124  }
125 
126  if ((el_message.find("Tree branches") != std::string::npos)
127  && (el_message.find("different numbers of entries") != std::string::npos)) {
128  el_severity = SeverityLevel::kFatal;
129  }
130 
131 
132  // Intercept some messages and downgrade the severity
133 
134  if ((el_message.find("no dictionary for class") != std::string::npos) ||
135  (el_message.find("already in TClassTable") != std::string::npos) ||
136  (el_message.find("matrix not positive definite") != std::string::npos) ||
137  (el_message.find("not a TStreamerInfo object") != std::string::npos) ||
138  (el_message.find("Problems declaring payload") != std::string::npos) ||
139  (el_message.find("Announced number of args different from the real number of argument passed") != std::string::npos) || // Always printed if gDebug>0 - regardless of whether warning message is real.
140  (el_location.find("Fit") != std::string::npos) ||
141  (el_location.find("TDecompChol::Solve") != std::string::npos) ||
142  (el_location.find("THistPainter::PaintInit") != std::string::npos) ||
143  (el_location.find("TUnixSystem::SetDisplay") != std::string::npos) ||
144  (el_location.find("TGClient::GetFontByName") != std::string::npos) ||
145  (el_message.find("nbins is <=0 - set to nbins = 1") != std::string::npos) ||
146  (el_message.find("nbinsy is <=0 - set to nbinsy = 1") != std::string::npos) ||
147  (level < kError and
148  (el_location.find("CINTTypedefBuilder::Setup")!= std::string::npos) and
149  (el_message.find("possible entries are in use!") != std::string::npos))) {
150  el_severity = SeverityLevel::kInfo;
151  }
152 
153  if (el_severity == SeverityLevel::kInfo) {
154  // Don't throw if the message is just informational.
155  die = false;
156  } else {
157  die = true;
158  }
159 
160  // Feed the message to the MessageLogger and let it choose to suppress or not.
161 
162  // Root has declared a fatal error. Throw an EDMException unless the
163  // message corresponds to a pending signal. In that case, do not throw
164  // but let the OS deal with the signal in the usual way.
165  if (die && (el_location != std::string("@SUB=TUnixSystem::DispatchSignals"))) {
166  std::ostringstream sstr;
167  sstr << "Fatal Root Error: " << el_location << "\n" << el_message << '\n';
168  edm::Exception except(edm::errors::FatalRootError, sstr.str());
169  except.addAdditionalInfo(except.message());
170  except.clearMessage();
171  throw except;
172 
173  }
174 
175  // Typically, we get here only for informational messages,
176  // but we leave the other code in just in case we change
177  // the criteria for throwing.
178  if (el_severity == SeverityLevel::kFatal) {
179  edm::LogError("Root_Fatal") << el_location << el_message;
180  } else if (el_severity == SeverityLevel::kSysError) {
181  edm::LogError("Root_Severe") << el_location << el_message;
182  } else if (el_severity == SeverityLevel::kError) {
183  edm::LogError("Root_Error") << el_location << el_message;
184  } else if (el_severity == SeverityLevel::kWarning) {
185  edm::LogWarning("Root_Warning") << el_location << el_message ;
186  } else if (el_severity == SeverityLevel::kInfo) {
187  edm::LogInfo("Root_Information") << el_location << el_message ;
188  }
189  }
190 
191  void RootErrorHandler(int level, bool, char const* location, char const* message) {
192  RootErrorHandlerImpl(level, location, message);
193  }
194 
195  extern "C" {
196 
197  static int full_write(int fd, const char *text)
198  {
199  const char *buffer = text;
200  size_t count = strlen(text);
201  ssize_t written = 0;
202  while (count)
203  {
204  written = write(fd, buffer, count);
205  if (written == -1)
206  {
207  if (errno == EINTR) {continue;}
208  else {return -errno;}
209  }
210  count -= written;
211  buffer += written;
212  }
213  return 0;
214  }
215 
216  static int full_read(int fd, char *inbuf, size_t len, int timeout_s=-1)
217  {
218  char *buf = inbuf;
219  size_t count = len;
220  ssize_t complete = 0;
221  std::chrono::time_point<std::chrono::steady_clock> end_time = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s);
222  int flags;
223  if (timeout_s < 0)
224  {
225  flags = O_NONBLOCK; // Prevents us from trying to set / restore flags later.
226  }
227  else if ((-1 == (flags = fcntl(fd, F_GETFL))))
228  {
229  return -errno;
230  }
231  if ((flags & O_NONBLOCK) != O_NONBLOCK)
232  {
233  if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK))
234  {
235  return -errno;
236  }
237  }
238  while (count)
239  {
240  if (timeout_s >= 0)
241  {
242  struct pollfd poll_info{fd, POLLIN, 0};
243  int ms_remaining = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-std::chrono::steady_clock::now()).count();
244  if (ms_remaining > 0)
245  {
246  if (poll(&poll_info, 1, ms_remaining) == 0)
247  {
248  if ((flags & O_NONBLOCK) != O_NONBLOCK)
249  {
250  fcntl(fd, F_SETFL, flags);
251  }
252  return -ETIMEDOUT;
253  }
254  }
255  else if (ms_remaining < 0)
256  {
257  if ((flags & O_NONBLOCK) != O_NONBLOCK)
258  {
259  fcntl(fd, F_SETFL, flags);
260  }
261  return -ETIMEDOUT;
262  }
263  }
264  complete = read(fd, buf, count);
265  if (complete == -1)
266  {
267  if (errno == EINTR) {continue;}
268  else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {continue;}
269  else
270  {
271  int orig_errno = errno;
272  if ((flags & O_NONBLOCK) != O_NONBLOCK)
273  {
274  fcntl(fd, F_SETFL, flags);
275  }
276  return -orig_errno;
277  }
278  }
279  count -= complete;
280  buf += complete;
281  }
282  if ((flags & O_NONBLOCK) != O_NONBLOCK) {
283  fcntl(fd, F_SETFL, flags);
284  }
285  return 0;
286  }
287 
288  static int full_cerr_write(const char *text)
289  {
290  return full_write(2, text);
291  }
292 
293  void sig_dostack_then_abort(int sig, siginfo_t*, void*) {
294 
295  const char* signalname = "unknown";
296  switch (sig) {
297  case SIGBUS:
298  signalname = "bus error";
299  break;
300  case SIGSEGV:
301  signalname = "segmentation violation";
302  break;
303  case SIGILL:
304  signalname = "illegal instruction";
305  default:
306  break;
307  }
308  full_cerr_write("\n\nA fatal system signal has occurred: ");
309  full_cerr_write(signalname);
310  full_cerr_write("\nThe following is the call stack containing the origin of the signal.\n"
311  "NOTE:The first few functions on the stack are artifacts of processing the signal and can be ignored\n\n");
312 
314 
315  full_cerr_write("\nA fatal system signal has occurred: ");
316  full_cerr_write(signalname);
317  full_cerr_write("\n");
318 
319  // For these three known cases, re-raise the signal so get the correct
320  // exit code.
321  if ((sig == SIGILL) || (sig == SIGSEGV) || (sig == SIGBUS))
322  {
323  signal(sig, SIG_DFL);
324  raise(sig);
325  }
326  else
327  {
328  ::abort();
329  }
330  }
331 
332  void sig_abort(int sig, siginfo_t*, void*) {
333  ::abort();
334  }
335  }
336 
337  void set_default_signals() {
338  signal(SIGILL, SIG_DFL);
339  signal(SIGSEGV, SIG_DFL);
340  signal(SIGBUS, SIG_DFL);
341  }
342 
343 } // end of unnamed namespace
344 
345 namespace edm {
346  namespace service {
347 
348  /*
349  * We've run into issues where GDB fails to print the thread which calls clone().
350  * To avoid this problem, we have an alternate approach below where the signal handler
351  * only reads/writes to a dedicated thread via pipes. The helper thread does the clone()
352  * invocation; we don't care if that thread is missing from the traceback in this case.
353  */
354  static void cmssw_stacktrace_fork();
355 
357  {
358  int toParent = childToParent_[1];
359  int fromParent = parentToChild_[0];
360  char buf[2]; buf[1] = '\0';
361  while(true)
362  {
363  int result = full_read(fromParent, buf, 1);
364  if (result < 0)
365  {
366  // To avoid a deadlock (this function is NOT re-entrant), reset signals
367  // We never set them back to the CMSSW handler because we assume the parent
368  // thread will abort for us.
369  set_default_signals();
370  close(toParent);
371  full_cerr_write("\n\nTraceback helper thread failed to read from parent: ");
372  full_cerr_write(strerror(-result));
373  full_cerr_write("\n");
374  ::abort();
375  }
376  if (buf[0] == '1')
377  {
378  set_default_signals();
380  full_write(toParent, buf);
381  }
382  else if (buf[0] == '2')
383  {
384  // We have just finished forking. Reload the file descriptors for thread
385  // communication.
386  close(toParent);
387  close(fromParent);
388  toParent = childToParent_[1];
389  fromParent = parentToChild_[0];
390  }
391  else if (buf[0] == '3')
392  {
393  break;
394  }
395  else
396  {
397  set_default_signals();
398  close(toParent);
399  full_cerr_write("\n\nTraceback helper thread got unknown command from parent: ");
400  full_cerr_write(buf);
401  full_cerr_write("\n");
402  ::abort();
403  }
404  }
405  }
406 
408  {
409  int result = full_write(parentToChild_[1], "1");
410  if (result < 0)
411  {
412  full_cerr_write("\n\nAttempt to request stacktrace failed: ");
413  full_cerr_write(strerror(-result));
414  full_cerr_write("\n");
415  return;
416  }
417  char buf[2]; buf[1] = '\0';
418  if ((result = full_read(childToParent_[0], buf, 1, 5*60)) < 0)
419  {
420  full_cerr_write("\n\nWaiting for stacktrace completion failed: ");
421  if (result == -ETIMEDOUT)
422  {
423  full_cerr_write("timed out waiting for GDB to complete.");
424  }
425  else
426  {
427  full_cerr_write(strerror(-result));
428  }
429  full_cerr_write("\n");
430  return;
431  }
432  }
433 
435  {
436  char child_stack[4*1024];
437  char *child_stack_ptr = child_stack + 4*1024;
438  // On Linux, we currently use jemalloc. This registers pthread_atfork handlers; these
439  // handlers are *not* async-signal safe. Hence, a deadlock is possible if we invoke
440  // fork() from our signal handlers. Accordingly, we use clone (not POSIX, but AS-safe)
441  // as that is closer to the 'raw metal' syscall and avoids pthread_atfork handlers.
442  int pid =
443 #ifdef __linux__
444  clone(edm::service::cmssw_stacktrace, child_stack_ptr, CLONE_VM|CLONE_FS|SIGCHLD, nullptr);
445 #else
446  fork();
447  if (child_stack_ptr) {} // Suppress 'unused variable' warning on non-Linux
448  if (pid == 0) {edm::service::cmssw_stacktrace(nullptr); ::abort();}
449 #endif
450  if (pid == -1)
451  {
452  full_cerr_write("(Attempt to perform stack dump failed.)\n");
453  }
454  else
455  {
456  int status;
457  if (waitpid(pid, &status, 0) == -1)
458  {
459  full_cerr_write("(Failed to wait on stack dump output.)\n");
460  }
461  if (status)
462  {
463  full_cerr_write("(GDB stack trace failed unexpectedly)\n");
464  }
465  }
466  }
467 
468  int cmssw_stacktrace(void * /*arg*/)
469  {
471  // NOTE: this is NOT async-signal-safe at CERN's lxplus service.
472  // CERN uses LD_PRELOAD to replace execv with a function from libsnoopy which
473  // calls dlsym.
474 #ifdef __linux__
475  syscall(SYS_execve, "/bin/sh", argv, __environ);
476 #else
477  execv("/bin/sh", argv);
478 #endif
479  ::abort();
480  return 1;
481  }
482 
483  static char pstackName[] = "(CMSSW stack trace helper)";
484  static char dashC[] = "-c";
487  int InitRootHandlers::parentToChild_[2] = {-1, -1};
488  int InitRootHandlers::childToParent_[2] = {-1, -1};
489  std::unique_ptr<std::thread> InitRootHandlers::helperThread_;
490 
492  : RootHandlers(),
493  unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler")),
494  resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler")),
495  loadAllDictionaries_(pset.getUntrackedParameter<bool>("LoadAllDictionaries")),
496  autoLibraryLoader_(loadAllDictionaries_ or pset.getUntrackedParameter<bool> ("AutoLibraryLoader"))
497  {
498 
499  if(unloadSigHandler_) {
500  // Deactivate all the Root signal handlers and restore the system defaults
501  gSystem->ResetSignal(kSigChild);
502  gSystem->ResetSignal(kSigBus);
503  gSystem->ResetSignal(kSigSegmentationViolation);
504  gSystem->ResetSignal(kSigIllegalInstruction);
505  gSystem->ResetSignal(kSigSystem);
506  gSystem->ResetSignal(kSigPipe);
507  gSystem->ResetSignal(kSigAlarm);
508  gSystem->ResetSignal(kSigUrgent);
509  gSystem->ResetSignal(kSigFloatingException);
510  gSystem->ResetSignal(kSigWindowChanged);
511  } else if(pset.getUntrackedParameter<bool>("AbortOnSignal")){
512  cachePidInfo();
513 
514  //NOTE: ROOT can also be told to abort on these kinds of problems BUT
515  // it requires an TApplication to be instantiated which causes problems
516  gSystem->ResetSignal(kSigBus);
517  gSystem->ResetSignal(kSigSegmentationViolation);
518  gSystem->ResetSignal(kSigIllegalInstruction);
519  installCustomHandler(SIGBUS,sig_dostack_then_abort);
520  sigBusHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
521  installCustomHandler(SIGBUS,sig_abort);
522  });
523  installCustomHandler(SIGSEGV,sig_dostack_then_abort);
524  sigSegvHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
525  installCustomHandler(SIGSEGV,sig_abort);
526  });
527  installCustomHandler(SIGILL,sig_dostack_then_abort);
528  sigIllHandler_ = std::shared_ptr<const void>(nullptr,[](void*) {
529  installCustomHandler(SIGILL,sig_abort);
530  });
532  }
533 
534  if(resetErrHandler_) {
535 
536  // Replace the Root error handler with one that uses the MessageLogger
537  SetErrorHandler(RootErrorHandler);
538  }
539 
540  // Enable automatic Root library loading.
541  if(autoLibraryLoader_) {
542  gInterpreter->SetClassAutoloading(1);
543  }
544 
545  // Set ROOT parameters.
546  TTree::SetMaxTreeSize(kMaxLong64);
547  TH1::AddDirectory(kFALSE);
548  //G__SetCatchException(0);
549 
550  // Set custom streamers
552 
553  // Load the library containing dictionaries for std:: classes, if not already loaded.
554  if (!hasDictionary(typeid(std::vector<std::vector<unsigned int> >))) {
555  TypeWithDict::byName("std::vector<std::vector<unsigned int> >");
556  }
557 
558  int debugLevel = pset.getUntrackedParameter<int>("DebugLevel");
559  if(debugLevel >0) {
560  gDebug = debugLevel;
561  }
562  }
563 
565  // close all open ROOT files
566  TIter iter(gROOT->GetListOfFiles());
567  TObject *obj = nullptr;
568  while(nullptr != (obj = iter.Next())) {
569  TFile* f = dynamic_cast<TFile*>(obj);
570  if(f) {
571  // We get a new iterator each time,
572  // because closing a file can invalidate the iterator
573  f->Close();
574  iter = TIter(gROOT->GetListOfFiles());
575  }
576  }
577  }
578 
580  //Tell Root we want to be multi-threaded
581  TThread::Initialize();
582  //When threading, also have to keep ROOT from logging all TObjects into a list
583  TObject::SetObjectStat(false);
584 
585  //Have to avoid having Streamers modify themselves after they have been used
586  TVirtualStreamerInfo::Optimize(false);
587  }
588 
590  static thread_local TThread guard;
591  }
592 
595  desc.setComment("Centralized interface to ROOT.");
596  desc.addUntracked<bool>("UnloadRootSigHandler", false)
597  ->setComment("If True, signals are handled by this service, rather than by ROOT.");
598  desc.addUntracked<bool>("ResetRootErrHandler", true)
599  ->setComment("If True, ROOT messages (e.g. errors, warnings) are handled by this service, rather than by ROOT.");
600  desc.addUntracked<bool>("AutoLibraryLoader", true)
601  ->setComment("If True, enables automatic loading of data dictionaries.");
602  desc.addUntracked<bool>("LoadAllDictionaries",false)
603  ->setComment("If True, loads all ROOT dictionaries.");
604  desc.addUntracked<bool>("AbortOnSignal",true)
605  ->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.");
606  desc.addUntracked<int>("DebugLevel",0)
607  ->setComment("Sets ROOT's gDebug value.");
608  descriptions.add("InitRootHandlers", desc);
609  }
610 
611  char *const *
613  return pstackArgv_;
614  }
615 
616  void
618  s_ignoreWarnings =false;
619  }
620 
621  void
623  s_ignoreWarnings = true;
624  }
625 
626  void
628  {
629  if (snprintf(pidString_, pidStringLength_-1, "gdb -quiet -p %d 2>&1 <<EOF |\n"
630  "set width 0\n"
631  "set height 0\n"
632  "set pagination no\n"
633  "thread apply all bt\n"
634  "EOF\n"
635  "/bin/sed -n -e 's/^\\((gdb) \\)*//' -e '/^#/p' -e '/^Thread/p'", getpid()) >= pidStringLength_)
636  {
637  std::ostringstream sstr;
638  sstr << "Unable to pre-allocate stacktrace handler information";
639  edm::Exception except(edm::errors::OtherCMS, sstr.str());
640  throw except;
641  }
642 
643  // These are initialized to -1; harmless to close an invalid FD.
644  // If this is called post-fork, we don't want to be communicating on
645  // these FDs as they are used internally by the parent.
646  close(childToParent_[0]);
647  close(childToParent_[1]);
648  childToParent_[0] = -1; childToParent_[1] = -1;
649  close(parentToChild_[0]);
650  close(parentToChild_[1]);
651  parentToChild_[0] = -1; parentToChild_[1] = -1;
652 
653  if (-1 == pipe2(childToParent_, O_CLOEXEC))
654  {
655  std::ostringstream sstr;
656  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
657  edm::Exception except(edm::errors::OtherCMS, sstr.str());
658  throw except;
659  }
660 
661  if (-1 == pipe2(parentToChild_, O_CLOEXEC))
662  {
663  close(childToParent_[0]); close(childToParent_[1]);
664  childToParent_[0] = -1; childToParent_[1] = -1;
665  std::ostringstream sstr;
666  sstr << "Failed to create child-to-parent pipes (errno=" << errno << "): " << strerror(errno);
667  edm::Exception except(edm::errors::OtherCMS, sstr.str());
668  throw except;
669  }
670 
671  helperThread_.reset(new std::thread(stacktraceHelperThread));
672  helperThread_->detach();
673  }
674 
675  } // end of namespace service
676 } // end of namespace edm
T getUntrackedParameter(std::string const &, T const &) const
virtual void enableWarnings_() override
static void cmssw_stacktrace_fork()
double seconds()
static char *const pstackArgv_[]
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setRefCoreStreamer(bool resetAll=false)
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
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)
void setComment(std::string const &value)
static char pidString_[pidStringLength_]
static char *const * getPstackArgv()
std::shared_ptr< const void > sigIllHandler_
tuple result
Definition: query.py:137
virtual void initializeThisThreadForUse() override
virtual void ignoreWarnings_() override
tuple fd
Definition: ztee.py:136
void addAdditionalInfo(std::string const &info)
Definition: Exception.cc:235
double f[11][100]
tuple text
Definition: runonSM.py:42
int cmssw_stacktrace(void *)
static std::unique_ptr< std::thread > helperThread_
static char pstackName[]
InitRootHandlers(ParameterSet const &pset, ActivityRegistry &iReg)
tuple pid
Definition: sysUtil.py:22
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
void watchPostForkReacquireResources(PostForkReacquireResources::slot_type const &iSlot)
virtual void willBeUsingThreads() override
static char dashC[]
static void fillDescriptions(ConfigurationDescriptions &descriptions)
SeverityLevel
bool hasDictionary(std::type_info const &)
#define O_NONBLOCK
Definition: SysFile.h:21
tuple level
Definition: testEve_cfg.py:34
tuple status
Definition: ntuplemaker.py:245