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) {
71 if (std::regex_match(input, matches, rgx)) {
72 buffer = abi::__cxa_demangle(matches.str(2).c_str(), buffer, bufferSize, &status);
73 fprintf(stderr,
"%s%s%s\n", matches.str(1).c_str(), buffer, matches.str(3).c_str());
77 fprintf(stderr,
"%s\n", input);
89 void raiseWithDefaultHandler(
int signum) noexcept {
90 signal(signum, SIG_DFL);
99 void signalHandler(
int signum) {
100 fprintf(stderr,
"Caught signal %d, backtrace follows:\n", signum);
103 void *addressList[MAX_FRAMES + 1];
104 size_t addressLength = backtrace(addressList, MAX_FRAMES);
105 if (addressLength == 0) {
106 fprintf(stderr,
" \n");
113 char **symbolList = backtrace_symbols(addressList, addressLength);
114 if (symbolList == NULL) {
115 fprintf(stderr,
"[backtrace_symbols] cannot dump trace, probably out of memory\n");
116 raiseWithDefaultHandler(signum);
123 size_t nameSize = NAME_SIZE_ESTIMATE;
124 char *name = (
char *)malloc(nameSize *
sizeof(
char));
126 fprintf(stderr,
"[malloc] cannot dump trace, probably out of memory\n");
127 raiseWithDefaultHandler(signum);
130 for (
size_t i = 0; i < addressLength; ++i) {
131 if (
char *buffer = demangleAndPrint(symbolList[i], name, &nameSize)) {
139 raiseWithDefaultHandler(signum);
144 Backtrace::Backtrace() noexcept : enabled(true) {
146 signal(SIGABRT, signalHandler);
147 signal(SIGSEGV, signalHandler);
148 signal(SIGILL, signalHandler);
149 signal(SIGFPE, signalHandler);
162 Backtrace::Backtrace() noexcept : enabled(false) {}