25 #if defined(LSST_UTILS_BACKTRACE_ENABLE) && (defined(__clang__) || defined(__GNUC__)) 35 #include "boost/regex.hpp" 45 static constexpr
size_t MAX_FRAMES = 128;
47 static constexpr
size_t NAME_SIZE_ESTIMATE = 1024;
61 char *demangleAndPrint(
char *input,
char *buffer,
size_t *bufferSize) noexcept {
65 boost::cmatch matches;
72 if (boost::regex_match(input, matches, rgx)) {
73 buffer = abi::__cxa_demangle(matches.str(2).c_str(), buffer, bufferSize, &status);
74 fprintf(stderr,
"%s%s%s\n", matches.str(1).c_str(), buffer, matches.str(3).c_str());
76 }
catch(
const boost::bad_expression &e) {
77 fprintf(stderr,
"[demangleAndPrint] %s\n", e.what());
80 fprintf(stderr,
"[demangleAndPrint] %s\n", e.
what());
83 fprintf(stderr,
"[demangleAndPrint] %s\n", e.
what());
86 fprintf(stderr,
"[demangleAndPrint] unknown error occurred in demangling\n");
104 void raiseWithDefaultHandler(
int signum) noexcept {
114 void signalHandler(
int signum) noexcept {
115 fprintf(stderr,
"Caught signal %d, backtrace follows:\n", signum);
118 void *addressList[MAX_FRAMES + 1];
119 size_t addressLength = backtrace(addressList, MAX_FRAMES);
120 if (addressLength == 0) {
128 char **symbolList = backtrace_symbols(addressList, addressLength);
129 if (symbolList == NULL) {
130 fprintf(stderr,
"[backtrace_symbols] cannot dump trace, probably out of memory\n");
131 raiseWithDefaultHandler(signum);
138 size_t nameSize = NAME_SIZE_ESTIMATE;
139 char *name = (
char *)
malloc(nameSize *
sizeof(
char));
141 fprintf(stderr,
"[malloc] cannot dump trace, probably out of memory\n");
142 raiseWithDefaultHandler(signum);
145 for (
size_t i = 0; i < addressLength; ++i) {
146 if (
char *buffer = demangleAndPrint(symbolList[i], name, &nameSize)) {
154 raiseWithDefaultHandler(signum);
159 Backtrace::Backtrace() noexcept : enabled(true) {
161 signal(SIGABRT, signalHandler);
162 signal(SIGSEGV, signalHandler);
163 signal(SIGILL, signalHandler);
164 signal(SIGFPE, signalHandler);
177 Backtrace::Backtrace() noexcept : enabled(false) {}