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 974 of file SealDebug.cxx.

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

◆ 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 1050 of file SealDebug.cxx.

1051 {
1052  struct rlimit core_limit;
1053  core_limit.rlim_cur = 0;
1054  core_limit.rlim_max = 0;
1055  setrlimit(RLIMIT_CORE, &core_limit);
1056 }

◆ 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 1030 of file SealDebug.cxx.

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

◆ 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 607 of file SealDebug.cxx.

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

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:221
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:16
Athena::DebugAids::s_stackTraceFd
static std::atomic< IOFD > s_stackTraceFd
The default output file descriptor for #stacktrace().
Definition: SealDebug.h:88