ATLAS Offline Software
Loading...
Searching...
No Matches
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
16
17
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
29using std::strlen;
30using std::sprintf;
31using std::free;
32
33
34// Helper to write literals
35# define MYWRITELIT(fd,str) MYWRITE(fd,str,sizeof(str)-1)
36
37
38namespace {
39bool stacktraceLine ATLAS_NOT_THREAD_SAFE (IOFD fd, unsigned long addr)
40{
41 Athena::DebugAids::stacktraceLine (fd, addr);
42 return false;
43}
44}
45
46
47namespace CxxUtils {
48
49
59void 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
#define IOFD_INVALID
Invalid channel descriptor constant.
Definition SealCommon.h:20
int IOFD
Type the system uses for channel descriptors.
Definition SealCommon.h:27
#define MYWRITE(fd, data, n)
Definition SealDebug.h:44
Define macros for attributes used to control the static checker.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
#define ATLAS_THREAD_SAFE
static IOFD stacktraceFd(IOFD fd=IOFD_INVALID)
Set and return the file descriptor for stack trace output.
#define MYWRITELIT(fd, str)
Definition exctrace.cxx:35
Generate stack trace backs from a caught exception.
std::string depth
tag string for intendation
Definition fastadd.cxx:46
void exctrace(const std::exception &e, IOFD fd=IOFD_INVALID)
Print out information for the last exception.
Definition exctrace.cxx:59