1
0
Fork 0

Codechange: [MacOS] use backtrace() instead of our custom variant (#11233)

As mentioned in the comment, we only did it ourselves as we once
were compatible with versions before 10.5. But that time has long
gone. So let's update the code to a bit more modern approach.
pull/11240/head
Patric Stout 2023-08-27 22:32:11 +02:00 committed by GitHub
parent 5e6b5d981f
commit d4312c59a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 7 additions and 57 deletions

View File

@ -21,6 +21,7 @@
#include <mach-o/arch.h> #include <mach-o/arch.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <cxxabi.h> #include <cxxabi.h>
#include <execinfo.h>
#ifdef WITH_UNOFFICIAL_BREAKPAD #ifdef WITH_UNOFFICIAL_BREAKPAD
# include <client/mac/handler/exception_handler.h> # include <client/mac/handler/exception_handler.h>
@ -83,67 +84,16 @@ class CrashLogOSX : public CrashLog {
void LogStacktrace(std::back_insert_iterator<std::string> &output_iterator) const override void LogStacktrace(std::back_insert_iterator<std::string> &output_iterator) const override
{ {
/* As backtrace() is only implemented in 10.5 or later,
* we're rolling our own here. Mostly based on
* http://stackoverflow.com/questions/289820/getting-the-current-stack-trace-on-mac-os-x
* and some details looked up in the Darwin sources. */
fmt::format_to(output_iterator, "\nStacktrace:\n"); fmt::format_to(output_iterator, "\nStacktrace:\n");
void **frame; void *trace[64];
#if defined(__ppc__) || defined(__ppc64__) int trace_size = backtrace(trace, lengthof(trace));
/* Apple says __builtin_frame_address can be broken on PPC. */
__asm__ volatile("mr %0, r1" : "=r" (frame));
#else
frame = (void **)__builtin_frame_address(0);
#endif
for (int i = 0; frame != nullptr && i < MAX_STACK_FRAMES; i++) { char **messages = backtrace_symbols(trace, trace_size);
/* Get IP for current stack frame. */ for (int i = 0; i < trace_size; i++) {
#if defined(__ppc__) || defined(__ppc64__) fmt::format_to(output_iterator, "{}\n", messages[i]);
void *ip = frame[2];
#else
void *ip = frame[1];
#endif
if (ip == nullptr) break;
/* Print running index. */
fmt::format_to(output_iterator, " [{:02}]", i);
Dl_info dli;
bool dl_valid = dladdr(ip, &dli) != 0;
const char *fname = "???";
if (dl_valid && dli.dli_fname) {
/* Valid image name? Extract filename from the complete path. */
const char *s = strrchr(dli.dli_fname, '/');
if (s != nullptr) {
fname = s + 1;
} else {
fname = dli.dli_fname;
}
}
/* Print image name and IP. */
fmt::format_to(output_iterator, " {:20s} {}", fname, (uintptr_t)ip);
/* Print function offset if information is available. */
if (dl_valid && dli.dli_sname != nullptr && dli.dli_saddr != nullptr) {
/* Try to demangle a possible C++ symbol. */
int status = -1;
char *func_name = abi::__cxa_demangle(dli.dli_sname, nullptr, 0, &status);
long int offset = (intptr_t)ip - (intptr_t)dli.dli_saddr;
fmt::format_to(output_iterator, " ({} + {})", func_name != nullptr ? func_name : dli.dli_sname, offset);
free(func_name);
}
fmt::format_to(output_iterator, "\n");
/* Get address of next stack frame. */
void **next = (void **)frame[0];
/* Frame address not increasing or not aligned? Broken stack, exit! */
if (next <= frame || !IS_ALIGNED(next)) break;
frame = next;
} }
free(messages);
fmt::format_to(output_iterator, "\n"); fmt::format_to(output_iterator, "\n");
} }