25 #if defined(LSST_UTILS_BACKTRACE_ENABLE) && (defined(__clang__) || defined(__GNUC__))
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 {
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());
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) {}