ATLAS Offline Software
exctrace.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
18 #include "CxxUtils/exctrace.h"
20 #include <cstring>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <iterator>
24 #include <execinfo.h>
25 #include <unistd.h>
26 #include <dlfcn.h>
27 
28 
29 using std::strlen;
30 using std::sprintf;
31 using std::free;
32 
33 
34 // Helper to write literals
35 # define MYWRITELIT(fd,str) MYWRITE(fd,str,sizeof(str)-1)
36 
37 
38 namespace {
39 bool stacktraceLine ATLAS_NOT_THREAD_SAFE (IOFD fd, unsigned long addr)
40 {
41  Athena::DebugAids::stacktraceLine (fd, addr);
42  return false;
43 }
44 }
45 
46 
47 namespace CxxUtils {
48 
49 
59 void exctrace (const std::exception& e, IOFD fd /*= IOFD_INVALID*/)
60 {
61  if (fd == IOFD_INVALID)
63 
64  typedef int (*get_last_trace_fn) (int max_depth, void* trace[]);
65  get_last_trace_fn get_last_trace = (get_last_trace_fn) dlsym (RTLD_DEFAULT, "exctrace_get_last_trace");
66 
67 
68  MYWRITELIT(fd, "Exception: ");
69  MYWRITE(fd, e.what(), strlen (e.what()));
70 
71  if (get_last_trace) {
72  void* trace[100];
73  int depth = get_last_trace (std::end(trace)-std::begin(trace), trace);
74 
75  MYWRITELIT(fd, "\n");
76  // Index 0 is __cxa_throw. Skip it.
77  for (int i = 1; i < depth; ++i) {
78  unsigned long ip =
79  reinterpret_cast<unsigned long> (trace[i]);
80  // A function that throws may have the call to __cxa_throw
81  // as the last instruction in the function. In that case, the IP
82  // we see here will be one beyond the end of the function,
83  // and we'll report the wrong function. So move back the IP
84  // slightly for the function that threw.
85  if (i == 1) --ip;
86 
87  // It's true that stacktraceLine is not really thread-safe.
88  // However, if we're here, things are going south fast anyway,
89  // so we'll just cross our fingers and try to shovel out as much
90  // information as we can.
91  [[maybe_unused]]
92  bool dum ATLAS_THREAD_SAFE = stacktraceLine (fd, ip);
93  }
94  }
95  else
96  MYWRITELIT(fd, " (no backtrace available).\n");
97 }
98 
99 
100 } // namespace CxxUtils
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
ATLAS_NOT_THREAD_SAFE
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
Definition: checker_macros.h:212
exctrace.h
Generate stack trace backs from a caught exception.
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
lumiFormat.i
int i
Definition: lumiFormat.py:85
IOFD
int IOFD
Type the system uses for channel descriptors.
Definition: SealCommon.h:27
CxxUtils
Definition: aligned_vector.h:29
calibdata.exception
exception
Definition: calibdata.py:496
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
Athena::DebugAids::stacktraceFd
static IOFD stacktraceFd(IOFD fd=IOFD_INVALID)
Set and return the file descriptor for stack trace output.
Definition: SealDebug.cxx:604
ReadFromCoolCompare.fd
fd
Definition: ReadFromCoolCompare.py:196
IOFD_INVALID
#define IOFD_INVALID
Invalid channel descriptor constant.
Definition: SealCommon.h:20
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
CxxUtils::exctrace
void exctrace(const std::exception &e, IOFD fd=IOFD_INVALID)
Print out information for the last exception.
Definition: exctrace.cxx:59
MYWRITE
#define MYWRITE(fd, data, n)
Definition: SealDebug.h:44
MYWRITELIT
#define MYWRITELIT(fd, str)
Definition: exctrace.cxx:35