ATLAS Offline Software
Static Public Member Functions | Static Private Attributes | List of all members
Athena::DebugAids Class Reference

Utilities for debugging support. More...

#include <SealDebug.h>

Collaboration diagram for Athena::DebugAids:

Static Public Member Functions

static IOFD stacktraceFd (IOFD fd=IOFD_INVALID)
 Set and return the file descriptor for stack trace output. More...
 
static void stacktrace ATLAS_NOT_THREAD_SAFE (IOFD fd=IOFD_INVALID)
 
static void coredump (int sig,...)
 Drop a core dump and continue. More...
 
static void stacktraceLine ATLAS_NOT_THREAD_SAFE (IOFD fd, unsigned long addr)
 
static void setStackTraceAddr2Line ATLAS_NOT_THREAD_SAFE (const char *path)
 
static unsigned long enableCoreFiles ()
 Try to enable core dump files by raising the soft size limit to the hard limit. More...
 
static void disableCoreFiles ()
 Disable core dump files by setting the soft limit to 0. More...
 

Static Private Attributes

static std::atomic< IOFDs_stackTraceFd = IOFD_INVALID
 The default output file descriptor for #stacktrace(). More...
 

Detailed Description

Utilities for debugging support.


Definition at line 72 of file SealDebug.h.

Member Function Documentation

◆ ATLAS_NOT_THREAD_SAFE() [1/3]

static void setStackTraceAddr2Line Athena::DebugAids::ATLAS_NOT_THREAD_SAFE ( const char *  path)
static

◆ ATLAS_NOT_THREAD_SAFE() [2/3]

static void stacktraceLine Athena::DebugAids::ATLAS_NOT_THREAD_SAFE ( IOFD  fd,
unsigned long  addr 
)
static

◆ ATLAS_NOT_THREAD_SAFE() [3/3]

static void stacktrace Athena::DebugAids::ATLAS_NOT_THREAD_SAFE ( IOFD  fd = IOFD_INVALID)
static

◆ coredump()

void Athena::DebugAids::coredump ( int  sig,
  ... 
)
static

Drop a core dump and continue.

Creates a core file for the current program state and continues execution. sig should be the number of the signal from which the program should appear to have died; this should a fatal signal that does cause a core file to be created (or SIGUSR1).

This works by forking the process and then killing the child with the given signal; the signal is automatically unblocked in the child to make sure the sure the signal is delivered. Thus the function returns only once, in the parent process.

This function can be safely installed directly as a signal handler. #Signal::handleFatal() will do so for SIGUSR1 with suitable options.

Note that this function does not change core dump resource limits, not even for the forked child process. If core files are disabled through resource limits, no core file will be created despite your explicit request to create one.

This concept was taken from DDD, the Data Display Debugger.

Definition at line 971 of file SealDebug.cxx.

972 {
973 #ifndef _WIN32
974  // FIXME: Forking vs. threads -- need to sort out what is safe.
975  // FIXME: Provide a resource limits interface so that core
976  // resource limits can be raised?
977 
978  pid_t corepid;
979  int status;
980 
981  ::unlink ("core");
982  if ((corepid = ::fork ()) == 0)
983  {
984  // In child: re-raise the signal, thus killing the process and
985  // producing a core dump. Make sure 1) the signal is not
986  // blocked so that we won't return to the caller, 2) we have a
987  // signal that is fatal, 3) the signal falls to its default
988  // handler to produce the dump.
989 
990 #ifdef SIGUSR1
991  // SIGUSR1 does not cause a core dump; use abort() instead
992  if (sig == SIGUSR1)
993  sig = SIGABRT; // Could be SIGIOT if SIGABRT is not defined
994 #endif
995  Signal::handle (sig, (Signal::HandlerType) (void*)SIG_DFL);
996  Signal::block (sig, false);
997  Signal::raise (sig);
998 
999  // Yikes, this shouldn't happen. ASSERT isn't right here. If
1000  // raise() failed to deliver the signal, abort() is unlikely
1001  // to work any better, but try it anyway. Then make sure we
1002  // die so that we won't return to the caller from the child.
1003  abort ();
1004  // cppcheck-suppress unreachableCode
1005  _exit (255);
1006  }
1007  else if (corepid > 0) {
1008  pid_t wait_pid;
1009  do {
1010  wait_pid = ::waitpid (corepid, &status, 0);
1011  } while (wait_pid == -1 && errno == EINTR);
1012  }
1013 #endif // !_WIN32
1014 }

◆ disableCoreFiles()

void Athena::DebugAids::disableCoreFiles ( )
static

Disable core dump files by setting the soft limit to 0.

This is equivalent to ulimit -Sc 0 in bash.

Definition at line 1047 of file SealDebug.cxx.

1048 {
1049  struct rlimit core_limit;
1050  core_limit.rlim_cur = 0;
1051  setrlimit(RLIMIT_CORE, &core_limit);
1052 }

◆ enableCoreFiles()

unsigned long Athena::DebugAids::enableCoreFiles ( )
static

Try to enable core dump files by raising the soft size limit to the hard limit.

There might be other reason though why the system does not produce core files, so this is only one of the prerequisites.

Returns the currently valid soft size limit.

This is equivalent to using ulimit -Sc in bash.

Definition at line 1027 of file SealDebug.cxx.

1028 {
1029  struct rlimit core_limit;
1030  getrlimit(RLIMIT_CORE, &core_limit);
1031 
1032  unsigned long old_limit = core_limit.rlim_cur;
1033  core_limit.rlim_cur = core_limit.rlim_max;
1034  if ( setrlimit(RLIMIT_CORE, &core_limit) == 0 ) {
1035  return core_limit.rlim_cur;
1036  }
1037  else {
1038  return old_limit;
1039  }
1040 }

◆ stacktraceFd()

IOFD Athena::DebugAids::stacktraceFd ( IOFD  fd = IOFD_INVALID)
static

Set and return the file descriptor for stack trace output.

If fd is the default invalid descriptor value, returns the current value without changing the setting. This value is only effective for #stacktrace(), but can be overridden by the argument given to that function.

Definition at line 604 of file SealDebug.cxx.

605 {
607  if (fd == IOFD_INVALID) {
608  if (old == IOFD_INVALID) {
609  s_stackTraceFd.compare_exchange_strong (old, STDERR_HANDLE);
610  return s_stackTraceFd;
611  }
612  }
613  else {
614  s_stackTraceFd.compare_exchange_strong (old, fd);
615  }
616  return old;
617 }

Member Data Documentation

◆ s_stackTraceFd

std::atomic< IOFD > Athena::DebugAids::s_stackTraceFd = IOFD_INVALID
staticprivate

The default output file descriptor for #stacktrace().


Definition at line 88 of file SealDebug.h.


The documentation for this class was generated from the following files:
pid_t
int32_t pid_t
Definition: FPGATrackSimTypes.h:19
Athena::Signal::raise
static int raise(int sig)
Raise the signal number sig.
Definition: SealSignal.cxx:377
IOFD
int IOFD
Type the system uses for channel descriptors.
Definition: SealCommon.h:27
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:215
Athena::Signal::HandlerType
void(* HandlerType)(int sig, siginfo_t *info, void *extra)
Signal handler type.
Definition: SealSignal.h:196
ReadFromCoolCompare.fd
fd
Definition: ReadFromCoolCompare.py:196
IOFD_INVALID
#define IOFD_INVALID
Invalid channel descriptor constant.
Definition: SealCommon.h:20
Athena::Signal::block
static void block(int sig, bool sense)
Block or unblock the signal number sig.
Definition: SealSignal.cxx:338
STDERR_HANDLE
#define STDERR_HANDLE
Definition: SealDebug.cxx:83
CSV_InDetExporter.old
old
Definition: CSV_InDetExporter.py:145
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
merge.status
status
Definition: merge.py:17
Athena::DebugAids::s_stackTraceFd
static std::atomic< IOFD > s_stackTraceFd
The default output file descriptor for #stacktrace().
Definition: SealDebug.h:88