ATLAS Offline Software
CoreDumpSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 // System includes
13 #include <ctime>
14 #include <cstdio>
15 #include <fcntl.h>
16 #include <errno.h>
17 #include <signal.h>
18 #include <time.h>
19 #include <sys/types.h>
20 #ifndef __APPLE__
21 #include <sys/sysinfo.h>
22 #else
23 #include <mach/task.h>
24 #include <mach/mach_init.h>
25 #include <unistd.h>
26 #endif
27 
28 // Package includes
29 #include "CoreDumpSvc.h"
30 
31 // ROOT includes
32 #include "TSystem.h"
33 
34 // Gaudi includes
35 #include "Gaudi/Property.h"
36 #include "GaudiKernel/IAlgorithm.h"
37 #include "GaudiKernel/IIncidentSvc.h"
38 #include "GaudiKernel/IAlgContextSvc.h"
39 #include "GaudiKernel/IAlgExecStateSvc.h"
40 #include "GaudiKernel/ServiceHandle.h"
41 #include "GaudiKernel/System.h"
42 #include "GaudiKernel/ConcurrencyFlags.h"
43 #include "GaudiKernel/EventContext.h"
44 
45 // Athena includes
47 #include "StoreGate/StoreGateSvc.h"
48 #include "CxxUtils/SealCommon.h"
49 #include "CxxUtils/SealSignal.h"
50 #include "CxxUtils/SealDebug.h"
53 
54 namespace {
55 
56  const char* const horizLine = "-------------------------------------------------------------------------------------\n";
57 
58  void ExitOnInt( int sig, siginfo_t*, void* ) {
59  if ( sig == SIGINT ) {
60  // called on user ^C
61  std::cout << std::endl;
62  std::cerr << "Athena CRITICAL stopped by user interrupt\n";
63  raise(SIGKILL);
64  }
65  }
66 
67 } // unnamed namespace
68 
69 
78 {
79  typedef std::map<int, struct sigaction> SigHandler_t;
80 
82  bool callOldHandler(true);
83  bool dumpCoreFile(false);
84  bool stackTrace(false);
85  bool fastStackTrace(false);
87  std::ostream* ostr(&std::cout);
88 
89  std::ostream& log ATLAS_NOT_THREAD_SAFE () { return *ostr; }
90 
95  {
96  // Careful: don't do anything here that might allocate memory.
97 
98  // Protect against recursion.
99  // We originally used a thread_local here --- but accessing
100  // a thread_local can result in a call to malloc.
101 
102  const int maxcalls = 64;
103  static std::atomic<int> ncalls (0);
104  if (++ncalls >= maxcalls) _exit (98);
105 
106  static std::mutex tidlist_mutex;
107  static size_t ntids ATLAS_THREAD_SAFE = 0;
108  static pthread_t tids[maxcalls] ATLAS_THREAD_SAFE;
109  {
110  pthread_t self = pthread_self();
111  std::lock_guard<std::mutex> lock (tidlist_mutex);
112  for (size_t i = 0; i < ntids; i++) {
113  if (pthread_equal (self, tids[i])) return;
114  }
115  if (ntids == maxcalls) _exit (98);
116  tids[ntids++] = self;
117  }
118 
119  // Count the number of threads trying to dump.
120  static std::atomic<int> inThreads = 0;
121  ++inThreads;
122 
123  const unsigned int timeoutSeconds = static_cast<unsigned int>(round(coreDumpSvc->m_timeout * 1e-9));
124 
125  if ( sig == SIGALRM) {
126  if (dumpCoreFile) {
127  log() << "Received SIGALRM. Aborting job..." << std::endl;
128  // Restore default abort handler that should create a core file
129  Athena::Signal::revert (SIGABRT);
130  std::abort();
131  }
132  else {
133  log() << "Received SIGALRM. Terminating job..." << std::endl;
134  _exit(97); // exit without raising any further signals
135  }
136  }
137 
138  // Only allow one thread past at a time.
139  // Try to assume as little as possible about the state of the library.
140  // We don't want to hang forever here, but we also don't want
141  // to call any library functions that might use signals under the hood.
142  // So use nanosleep() to do the delay --- that's defined to be
143  // independent of signals.
144  static std::mutex threadMutex;
145  const timespec one_second { 1, 0 };
146  {
147  unsigned int waits = 0;
148  while (!threadMutex.try_lock()) {
149  nanosleep (&one_second, nullptr);
150  if (++waits > timeoutSeconds) _exit (97);
151  }
152  }
153 
154  // setup timeout
155  if ( timeoutSeconds > 0 && (sig == SIGSEGV || sig == SIGBUS || sig == SIGABRT) ) {
156  // This will trigger SIGALRM, which we then handle ourselves above
157  alarm(timeoutSeconds);
158  }
159 
160  // Do fast stack trace before anything that might touch the heap.
161  // For extra paranoia, avoid iostreams/stdio and use write() directly.
162  if (fastStackTrace) {
163  write (1, horizLine, strlen(horizLine));
164  const char* msg = "Producing (fast) stack trace...\n";
165  write (1, msg, strlen (msg));
166  write (1, horizLine, strlen(horizLine));
167  Athena::Signal::fatalDump (sig, info, extra,
172  write (1, "\n", 1);
173  }
174 
175  std::cout.flush();
176  std::cerr.flush();
177 
178  if (coreDumpSvc) {
180  coreDumpSvc->print();
181  }
182 
183  if (gSystem && stackTrace) {
184  log() << horizLine << "Producing stack trace (can be slow, check gdb process)...\n"
185  << horizLine << std::flush;
186  gSystem->StackTrace();
187  log() << std::endl;
188  }
189 
190  if (callOldHandler) {
191  // Call previous signal handler
192  // Need to distinguish between the two different types
193  const struct sigaction& oact = oldSigHandler[sig];
194  log() << horizLine << "Invoking previous signal handler (can be slow, check gdb process)...\n"
195  << horizLine << std::flush;
196  if ( oact.sa_flags & SA_SIGINFO ) {
197  oact.sa_sigaction(sig, info, extra);
198  }
199  else if (oact.sa_handler != SIG_DFL && oact.sa_handler != SIG_IGN ) {
200  oact.sa_handler(sig);
201  }
202  else {
203  log() << "Could not invoke previous signal handler" << std::endl;
204  }
205  }
206 
207  // This thread is done dumping.
208  threadMutex.unlock();
209  --inThreads;
210 
211  if (coreDumpSvc && (sig == SIGSEGV || sig == SIGBUS || sig == SIGABRT) ) {
212  // Don't terminate the program while there are other threads
213  // trying to dump (but don't wait forever either).
214  unsigned int waits = 0;
215  while (inThreads > 0 && waits < timeoutSeconds) {
216  nanosleep (&one_second, nullptr);
217  }
218 
219  if (dumpCoreFile) {
220  log() << "Aborting job... " << std::endl;
221  // Restore default abort handler that should create a core file
222  Athena::Signal::revert (SIGABRT);
223  std::abort();
224  }
225 
226  // Exit now on a fatal signal; otherwise, we can hang.
227  _exit (99);
228  }
229  }
230 
231 }
232 
233 //================================================================================
234 // C'tor, D'tor, Property handler
235 //================================================================================
236 CoreDumpSvc::CoreDumpSvc( const std::string& name, ISvcLocator* pSvcLocator ) :
237  base_class( name, pSvcLocator )
238 {
239  // Set us as the current instance
241 
242  m_callOldHandler.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
243  m_dumpCoreFile.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
244  m_stackTrace.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
245  m_fastStackTrace.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
246  m_coreDumpStream.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
247  m_fatalHandlerFlags.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
248  m_killOnSigInt.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this);
249  // Allocate for 2 slots just for now.
250  m_usrCoreDumps.resize(2);
251  m_sysCoreDumps.resize(2);
252 }
253 
255 {
257 }
258 
259 void CoreDumpSvc::propertyHandler(Gaudi::Details::PropertyBase& p)
260 {
265 
266  if ( p.name()==m_coreDumpStream.name() ) {
267  const std::string val = p.toString();
268  if ( val=="stdout" ) {
269  CoreDumpSvcHandler::ostr = &std::cout;
270  }
271  else if ( val=="stderr" ) {
272  CoreDumpSvcHandler::ostr = &std::cerr;
273  }
274  else {
275  ATH_MSG_WARNING("'" << val << "' not valid for " << m_coreDumpStream.name()
276  << ": " << m_coreDumpStream.documentation());
277  }
278  } else if ( p.name() == m_fatalHandlerFlags.name() ) {
279  if (m_fatalHandlerFlags.fromString(p.toString()).isSuccess()) {
280  if (m_fatalHandlerFlags != 0) {
281  Athena::Signal::handleFatal(nullptr, IOFD_INVALID, nullptr, nullptr, m_fatalHandlerFlags);
282  }
283  } else {
284  ATH_MSG_INFO("could not convert [" << p.toString() << "] to integer");
285  }
286  }
287  else if (p.name() == m_killOnSigInt.name()) {
288  if (m_killOnSigInt.fromString(p.toString()).isSuccess()) {
289  if (m_killOnSigInt) {
290  ATH_MSG_DEBUG("Will kill job on SIGINT (Ctrl-C)");
291  Athena::Signal::handle( SIGINT, ExitOnInt );
292  }
293  }
294  else {
295  ATH_MSG_WARNING("Could not convert [" << p.toString() << "] to bool");
296  }
297  }
298 
299 }
300 
301 //================================================================================
302 // IService implementation
303 //================================================================================
305 {
306  if (m_fatalHandlerFlags != 0) {
307  ATH_MSG_INFO("install f-a-t-a-l handler... (flag = " << m_fatalHandlerFlags.value() << ")");
308  Athena::Signal::handleFatal(nullptr, IOFD_INVALID, nullptr, nullptr, m_fatalHandlerFlags);
309  }
310 
311  if (m_killOnSigInt) {
312  ATH_MSG_DEBUG("Will kill job on SIGINT (Ctrl-C)");
313  Athena::Signal::handle( SIGINT, ExitOnInt );
314  }
315 
316  if ( installSignalHandler().isFailure() ) {
317  ATH_MSG_ERROR ("Could not install signal handlers");
318  return StatusCode::FAILURE;
319  }
320 
321  // Register incident handler
322  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
323  if ( !incSvc.retrieve().isSuccess() ) {
324  ATH_MSG_WARNING ("Unable to retrieve the IncidentSvc");
325  }
326  else {
327  incSvc->addListener(this, IncidentType::BeginRun);
328  incSvc->addListener(this, IncidentType::BeginEvent);
329  incSvc->addListener(this, IncidentType::EndRun);
330  incSvc->addListener(this, IncidentType::EndEvent);
331  incSvc->addListener(this,"StoreCleared");
332  }
333 
334  return StatusCode::SUCCESS;
335 }
336 
338 {
339  auto numSlots = std::max<size_t>(1, Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents());
340  m_usrCoreDumps.resize(numSlots);
341  m_sysCoreDumps.resize(numSlots);
342  return StatusCode::SUCCESS;
343 }
344 
346 {
347  ATH_MSG_DEBUG ("Finalizing " << name());
348 
349  if ( uninstallSignalHandler().isFailure() ) {
350  ATH_MSG_WARNING ("Could not uninstall signal handlers");
351  return StatusCode::FAILURE;
352  }
353 
354  return StatusCode::SUCCESS;
355 }
356 
357 //================================================================================
358 // ICoreDumpSvc implementation
359 //================================================================================
360 
361 //----------------------------------------------------------------------
362 // Set a name/value pair in the core dump record
363 //----------------------------------------------------------------------
364 void CoreDumpSvc::setCoreDumpInfo( const std::string& name, const std::string& value )
365 {
366  setCoreDumpInfo(Gaudi::Hive::currentContext(), name, value);
367 }
368 
369 void CoreDumpSvc::setCoreDumpInfo( const EventContext& ctx, const std::string& name, const std::string& value )
370 {
371  auto slot = ctx.valid() ? ctx.slot() : 0;
372  m_usrCoreDumps.at(slot)[name] = value;
373 }
374 
375 //----------------------------------------------------------------------
376 // Print all core dump records
377 //----------------------------------------------------------------------
379 {
380  // Print a FATAL message but don't use the MsgStream anymore once we crashed
381  CoreDumpSvcHandler::log() << name() << " FATAL Caught fatal signal. Printing details to "
382  << m_coreDumpStream.value()
383  << (m_dumpCoreFile ? ". Will try to produce a core dump file on exit." : ".")
384  << std::endl;
385 
387 }
388 
389 //----------------------------------------------------------------------
390 // Print all core dump records
391 //----------------------------------------------------------------------
392 std::string CoreDumpSvc::dump() const
393 {
394  std::ostringstream os;
395  char buf[26];
396  const time_t now = time(nullptr);
397 
398  os << "-------------------------------------------------------------------------------------" << "\n";
399  os << "Core dump from " << name() << " on " << System::hostName()
400  << " at " << ctime_r(&now, buf) /*<< "\n"*/; // ctime adds "\n"
401  os << "\n";
402 
403  // Print additional information if available
404  if (m_siginfo) {
405  int signo = m_siginfo->si_signo; // shorthand
406 
407  os << "Caught signal " << signo
408  << "(" << strsignal(signo) << "). Details: "
409  << "\n";
410 
411  os << " errno = " << m_siginfo->si_errno
412  << ", code = " << m_siginfo->si_code
413  << " (" << Athena::Signal::describe(signo, m_siginfo->si_code) << ")"
414  << "\n";
415 
416  os << " pid = " << m_siginfo->si_pid
417  << ", uid = " << m_siginfo->si_uid
418  << "\n";
419 
420 #ifndef __APPLE__
421  // These are set if the POSIX signal sender passed them.
422  os << " value = (" << m_siginfo->si_int << ", "
423  << std::hex << m_siginfo->si_ptr << ")" << std::dec << "\n";
424 #endif
425 
426  // memory usage informations
428 
429  const long pagesz = sysconf(_SC_PAGESIZE);
430  os << " vmem = " << s.vm_pages*pagesz/1024./1024. << " MB\n"
431  << " rss = " << s.rss_pages*pagesz/1024./1024. << " MB\n";
432 
433 #ifndef __APPLE__
434  // more memory usage informations (system wide stuff)
435  // see sysinfo(2)
436 
437  {
438  struct sysinfo sys;
439  if ( 0 == sysinfo(&sys) ) {
440  // all sizes are reported in sys.mem_unit bytes
441  const float mem_units = sys.mem_unit/(1024.*1024.);
442  os << " total-ram = " << sys.totalram * mem_units << " MB\n"
443  << " free-ram = " << sys.freeram * mem_units << " MB\n"
444  << " buffer-ram= " << sys.bufferram* mem_units << " MB\n"
445  << " total-swap= " << sys.totalswap* mem_units << " MB\n"
446  << " free-swap = " << sys.freeswap * mem_units << " MB\n";
447  }
448  }
449 #endif
450 
451  // This is the interesting address for memory faults.
452  if (signo == SIGILL || signo == SIGFPE || signo == SIGSEGV || signo == SIGBUS)
453  os << " addr = " << std::hex << m_siginfo->si_addr << std::dec << "\n";
454 
455  os << "\n";
456  }
457 
458  os << "Event counter: " << m_eventCounter << "\n";
459 
460 
461  IAlgExecStateSvc* algExecStateSvc(nullptr);
462  IAlgContextSvc* algContextSvc(nullptr);
463 
464  // Use AlgExecStateSvc in MT, otherwise AlgContextSvc
465  if (Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents() > 0) {
466  service("AlgExecStateSvc", algExecStateSvc, /*createIf=*/ false).ignore();
467  }
468  else {
469  service("AlgContextSvc", algContextSvc, /*createIf=*/ false).ignore();
470  }
471 
472  // Loop over all slots
473  for (size_t t=0; t < m_sysCoreDumps.size(); ++t){
474 
475  // Currently executing algorithm(s)
476  std::string currentAlg;
477  if (algExecStateSvc) {
478  ATH_MSG_DEBUG("Using AlgExecStateSvc to determine current algorithm(s)");
479  try {
480  // We copy on purpose to avoid modification while we examine it
481  auto states = algExecStateSvc->algExecStates(EventContext(0,t));
482  for (const auto& kv : states) {
483  if (kv.second.state()==AlgExecState::State::Executing)
484  currentAlg += (kv.first + " ");
485  }
486  }
487  catch (const GaudiException&) { // can happen if we get called before any algo execution
488  ATH_MSG_INFO("No information from AlgExecStateSvc because no algorithm was executed yet.");
489  }
490  }
491  else if (algContextSvc) {
492  ATH_MSG_DEBUG("Using AlgContextSvc to determine current algorithm");
493  IAlgorithm* alg = algContextSvc->currentAlg();
494  if (alg) currentAlg = alg->name();
495  }
496  else {
497  ATH_MSG_WARNING("AlgExecStateSvc or AlgContextSvc not available. Cannot determine current algorithm.");
498  }
499 
500  if (currentAlg.empty()) currentAlg = "<NONE>";
501  os << "Slot " << std::setw(3) << t << " : Current algorithm = " << currentAlg << std::endl;
502 
503  // System core dump
504  auto &sys = m_sysCoreDumps.at(t);
505  if (!sys.LastInc.empty()) {
506  os << " : Last Incident = " << sys.LastInc << std::endl
507  << " : Event ID = " << sys.EvId << std::endl;
508  }
509 
510  // User core dump
511  auto &usr = m_usrCoreDumps.at(t);
512  if (!usr.empty()) {
513  for (auto &s : usr) {
514  os << " : (usr) " << s.first << " = " << s.second << std::endl;
515  }
516  }
517  }
518 
519  if (algContextSvc) {
520  os << "Algorithm stack: ";
521  if ( algContextSvc->algorithms().empty() ) os << "<EMPTY>" << "\n";
522  else {
523  os << "\n";
524  for (auto alg : algContextSvc->algorithms()) {
525  if (alg) os << " " << alg->name() << "\n";
526  }
527  }
528  }
529 
530  os << horizLine;
531  os << "| AtlasBaseDir : " << std::setw(66) << getenv("AtlasBaseDir") << " |\n";
532  os << "| AtlasVersion : " << std::setw(66) << getenv("AtlasVersion") << " |\n";
533  os << "| BINARY_TAG : " << std::setw(66) << getenv("BINARY_TAG") << " |\n";
534  os << horizLine;
535  os << " Note: to see line numbers in below stacktrace you might consider running following :\n";
536  os << " atlasAddress2Line --file <logfile>\n";
537 
538  IAthenaSummarySvc *iass(nullptr);
539  if (service("AthenaSummarySvc",iass,false).isSuccess() && iass) {
540  iass->addSummary("CoreDumpSvc",os.str());
541  iass->setStatus(1);
542  iass->createSummary().ignore();
543  }
544 
545  return os.str();
546 }
547 
548 //================================================================================
549 // IIncidentHandler implementation
550 //================================================================================
551 
552 void CoreDumpSvc::handle(const Incident& incident)
553 {
554  //handle is single threaded in context;
555  auto slot = incident.context().valid() ? incident.context().slot() : 0;
556  auto &currRec = m_sysCoreDumps.at(slot);
557 
558  currRec.LastInc = incident.source() + ":" + incident.type();
559 
560  std::ostringstream oss;
561  oss << incident.context().eventID();
562  currRec.EvId = oss.str();
563 
564  if (incident.type()==IncidentType::BeginEvent) {
565  // Set up an alternate stack for this thread, if not already done.
566  setAltStack();
567  ++m_eventCounter;
568  } else if (incident.type() == "StoreCleared") {
569  // Try to force reallocation.
570  auto newstr = currRec.EvId;
571  // Intentional:
572  // cppcheck-suppress selfAssignment
573  newstr[0] = newstr[0];
574  currRec.EvId = newstr;
575  }
576 
577 }
578 
579 //================================================================================
580 // Helpers for signal handler
581 //================================================================================
582 
583 //----------------------------------------------------------------------
584 // Install signal handler
585 //----------------------------------------------------------------------
586 StatusCode CoreDumpSvc::installSignalHandler ATLAS_NOT_THREAD_SAFE ()
587 {
588  ATH_MSG_DEBUG ("Installing signal handler");
589  std::ostringstream oss;
590 
591  for (auto sig : m_signals) {
592 #ifndef __APPLE__
593  if (sig<1 || sig>SIGRTMAX) {
594  ATH_MSG_WARNING ("Invalid signal number " << sig << ". Ignoring.");
595  continue;
596  }
597 #endif
598  oss << sig << "(" << strsignal(sig) << ") ";
599 
600  // Set up an alternate stack for this thread.
601  setAltStack();
602 
603  // Install new signal handler and backup old one
604  struct sigaction sigact;
605  memset (&sigact, 0, sizeof(sigact));
606  sigact.sa_sigaction = CoreDumpSvcHandler::action;
607  sigemptyset(&sigact.sa_mask);
608  sigact.sa_flags = SA_SIGINFO + SA_ONSTACK;
609  int ret = sigaction(sig, &sigact, &(CoreDumpSvcHandler::oldSigHandler[sig]));
610  if ( ret!=0 ) {
611  ATH_MSG_ERROR ("Error on installing handler for signal " << sig
612  << ": " << strerror(errno));
613  return StatusCode::FAILURE;
614  }
615  }
616  ATH_MSG_INFO ("Handling signals: " << oss.str());
617 
618  return StatusCode::SUCCESS;
619 }
620 
621 //----------------------------------------------------------------------
622 // Uninstall signal handler
623 //----------------------------------------------------------------------
624 StatusCode CoreDumpSvc::uninstallSignalHandler ATLAS_NOT_THREAD_SAFE ()
625 {
626  ATH_MSG_DEBUG ("Uninstalling signal handler");
627 
628  StatusCode sc = StatusCode::SUCCESS;
629 
630  for (const auto& kv : CoreDumpSvcHandler::oldSigHandler) {
631  int ret = sigaction(kv.first, &(kv.second), nullptr);
632  if ( ret!=0 ) {
633  sc = StatusCode::FAILURE;
634  ATH_MSG_WARNING("Error on uninstalling handler for signal " << kv.first
635  << ": " << strerror(errno));
636  }
637  }
638  return sc;
639 }
640 
641 
642 // Set an alternate stack to use for doing stack traces, so that we
643 // can continue even if our primary stack is corrupt / exhausted.
644 // Reserve 2MB on top of the minimum required for a signal handler.
645 // This sets the alternate stack for the current thread, if it hasn't
646 // already been done.
648 {
649  std::vector<uint8_t>& stack = s_stack;
650  if (stack.empty()) {
651  stack.resize (std::max (SIGSTKSZ, MINSIGSTKSZ) + 2*1024*1024);
652  stack_t ss;
653  ss.ss_sp = stack.data();
654  ss.ss_flags = 0;
655  ss.ss_size = stack.size();
656  sigaltstack (&ss, nullptr);
657  }
658 }
659 
660 
661 thread_local std::vector<uint8_t> CoreDumpSvc::s_stack;
IAthenaSummarySvc::createSummary
virtual StatusCode createSummary()=0
grepfile.info
info
Definition: grepfile.py:38
CoreDumpSvcHandler::oldSigHandler
SigHandler_t oldSigHandler
old signal handlers
Definition: CoreDumpSvc.cxx:81
04Plot.stack
list stack
Definition: 04Plot.py:10
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:53
CoreDumpSvc.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
SGout2dot.alg
alg
Definition: SGout2dot.py:243
CoreDumpSvc::start
virtual StatusCode start() override
Definition: CoreDumpSvc.cxx:337
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
max
#define max(a, b)
Definition: cfImp.cxx:41
Athena::Signal::FATAL_DUMP_STACK
static const int FATAL_DUMP_STACK
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:130
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
siginfo_t
Definition: SealSignal.h:77
FullCPAlgorithmsTest_eljob.flush
flush
Definition: FullCPAlgorithmsTest_eljob.py:168
CoreDumpSvc::m_fastStackTrace
Gaudi::Property< bool > m_fastStackTrace
Definition: CoreDumpSvc.h:113
CoreDumpSvcHandler::SigHandler_t
std::map< int, struct sigaction > SigHandler_t
Definition: CoreDumpSvc.cxx:79
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
CoreDumpSvc::m_sysCoreDumps
std::vector< sysDumpRec > m_sysCoreDumps
Core dump info collected by this service
Definition: CoreDumpSvc.h:93
IAthenaSummarySvc
Abstract produces summary of Athena stuff.
Definition: IAthenaSummarySvc.h:18
initialize
void initialize()
Definition: run_EoverP.cxx:894
SealDebug.h
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
ATLAS_NOT_THREAD_SAFE
void CoreDumpSvc::print ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
Definition: CoreDumpSvc.cxx:378
CoreDumpSvc::m_callOldHandler
Gaudi::Property< bool > m_callOldHandler
Definition: CoreDumpSvc.h:104
CoreDumpSvcHandler::dumpCoreFile
bool dumpCoreFile(false)
dump core file on exit?
SealCommon.h
Collecting a few shared bits and pieces from SEAL headers.
CoreDumpSvc::~CoreDumpSvc
virtual ~CoreDumpSvc() ATLAS_CTORDTOR_NOT_THREAD_SAFE
Destructor.
Definition: CoreDumpSvc.cxx:254
CoreDumpSvc::m_coreDumpStream
Gaudi::Property< std::string > m_coreDumpStream
Definition: CoreDumpSvc.h:116
CoreDumpSvcHandler::fastStackTrace
bool fastStackTrace(false)
produce fast stack trace using CxxUtils/Seal
athena.value
value
Definition: athena.py:122
CoreDumpSvc::setAltStack
void setAltStack()
Set up an alternate stack for the current thread.
Definition: CoreDumpSvc.cxx:647
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
CoreDumpSvc::m_eventCounter
std::atomic< EventID::event_number_t > m_eventCounter
Event counter.
Definition: CoreDumpSvc.h:95
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
CoreDumpSvc::setCoreDumpInfo
virtual void setCoreDumpInfo(const std::string &name, const std::string &value) override
Set a name/value pair in the core dump record.
Definition: CoreDumpSvc.cxx:364
Athena::Signal::FATAL_DUMP_SIG
static const int FATAL_DUMP_SIG
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:126
CoreDumpSvc
Service to print additional information before a crash.
Definition: CoreDumpSvc.h:46
python.handimod.now
now
Definition: handimod.py:675
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CoreDumpSvc::m_timeout
Gaudi::Property< double > m_timeout
Definition: CoreDumpSvc.h:123
lumiFormat.i
int i
Definition: lumiFormat.py:92
SealSignal.h
This is the signal handler from SEAL, adapted to build in Atlas, after the drop of that project.
CoreDumpSvc::m_siginfo
siginfo_t * m_siginfo
Pointer to siginfo_t struct (set by signal handler)
Definition: CoreDumpSvc.h:94
CoreDumpSvcHandler::ATLAS_NOT_THREAD_SAFE
std::ostream &log ATLAS_NOT_THREAD_SAFE()
convenience method for logging
Definition: CoreDumpSvc.cxx:89
ret
T ret(T t)
Definition: rootspy.cxx:260
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CoreDumpSvcHandler::coreDumpSvc
CoreDumpSvc * coreDumpSvc(nullptr)
pointer to CoreDumpSvc
urldecode::states
states
Definition: urldecode.h:39
python.ByteStreamConfig.write
def write
Definition: Event/ByteStreamCnvSvc/python/ByteStreamConfig.py:248
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:215
CoreDumpSvc::CoreDumpSvc
CoreDumpSvc()
Default constructor (do not use)
Athena::DebugAids::stacktraceFd
static IOFD stacktraceFd(IOFD fd=IOFD_INVALID)
Set and return the file descriptor for stack trace output.
Definition: SealDebug.cxx:604
CoreDumpSvc::dump
virtual std::string dump() const override
Print all core dump records.
Definition: CoreDumpSvc.cxx:392
CoreDumpSvc::handle
virtual void handle(const Incident &incident) override
Incident listener.
Definition: CoreDumpSvc.cxx:552
Athena::Signal::FATAL_DUMP_CONTEXT
static const int FATAL_DUMP_CONTEXT
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:138
CoreDumpSvc::setSigInfo
void setSigInfo(siginfo_t *info)
Set pointer to siginfo_t struct.
Definition: CoreDumpSvc.h:139
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
CoreDumpSvcHandler
Signal handler for CoreDumpSvc.
Definition: CoreDumpSvc.cxx:78
python.handimod.extra
int extra
Definition: handimod.py:522
CoreDumpSvc::m_dumpCoreFile
Gaudi::Property< bool > m_dumpCoreFile
Definition: CoreDumpSvc.h:107
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
IOFD_INVALID
#define IOFD_INVALID
Invalid channel descriptor constant.
Definition: SealCommon.h:20
athena_statm
Definition: read_athena_statm.h:13
read_athena_statm.h
CoreDumpSvc::m_killOnSigInt
Gaudi::Property< bool > m_killOnSigInt
Definition: CoreDumpSvc.h:127
CoreDumpSvc::m_stackTrace
Gaudi::Property< bool > m_stackTrace
Definition: CoreDumpSvc.h:110
read_athena_statm
struct athena_statm read_athena_statm()
Definition: read_athena_statm.cxx:15
Athena::Signal::describe
static const char * describe(int sig, int code)
Return the description for signal info code code for signal number sig.
Definition: SealSignal.cxx:968
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
SCT_ConditionsAlgorithms::CoveritySafe::getenv
std::string getenv(const std::string &variableName)
get an environment variable
Definition: SCT_ConditionsUtilities.cxx:17
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
Athena::Signal::handle
static HandlerType handle(int sig, HandlerType handler, const sigset_t *blockMask=0)
Install a new signal handler handler for signal number sig and returns the old handler.
Definition: SealSignal.cxx:277
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.action
action
Definition: CaloScaleNoiseConfig.py:77
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
CoreDumpSvc::m_usrCoreDumps
std::vector< UserCore_t > m_usrCoreDumps
User defined core dump info.
Definition: CoreDumpSvc.h:92
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
CoreDumpSvcHandler::callOldHandler
bool callOldHandler(true)
forward calls to old handlers?
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
CoreDumpSvc::s_stack
static thread_local std::vector< uint8_t > s_stack
Definition: CoreDumpSvc.h:97
Athena::Signal::revert
static void revert(int sig)
Revert the signal number sig back to its default behaviour.
Definition: SealSignal.cxx:326
checker_macros.h
Define macros for attributes used to control the static checker.
FourMomUtils::dump
std::ostream & dump(std::ostream &out, const I4MomIter iBeg, const I4MomIter iEnd)
Helper to stream out a range of I4Momentum objects.
Definition: P4Dumper.h:24
StoreGateSvc.h
IAthenaSummarySvc::setStatus
virtual void setStatus(int)=0
CoreDumpSvc::m_fatalHandlerFlags
Gaudi::Property< int > m_fatalHandlerFlags
Definition: CoreDumpSvc.h:119
CoreDumpSvcHandler::stackTrace
bool stackTrace(false)
produce stack trace?
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
IAthenaSummarySvc.h
IAthenaSummarySvc::addSummary
virtual void addSummary(const std::string &, const std::string &)=0
sigemptyset
#define sigemptyset(x)
Definition: SealSignal.h:82
ServiceHandle< IIncidentSvc >