Commit 2a41679b authored by Chad Austin's avatar Chad Austin Committed by Facebook GitHub Bot

use FOLLY_HAVE_BACKTRACE to guard execinfo.h and usage of backtrace(3)

Summary:
FOLLY_USE_SYMBOLIZER is a poor guard for the existence of execinfo.h
and backtrace(3), which is widely available on unix platforms, but not
available on Android NDK. Instead, introduce FOLLY_HAVE_BACKTRACE and
have CMake detect its availability.

Reviewed By: yfeldblum, luciang

Differential Revision: D23361495

fbshipit-source-id: 4409363f3eaa754977a93e1f006c5911d8e32020
parent 6e269d82
......@@ -70,6 +70,7 @@
#cmakedefine FOLLY_HAVE_LIBUNWIND 1
#cmakedefine FOLLY_HAVE_DWARF 1
#cmakedefine FOLLY_HAVE_ELF 1
#cmakedefine FOLLY_HAVE_BACKTRACE 1
#cmakedefine FOLLY_USE_SYMBOLIZER 1
#define FOLLY_DEMANGLE_MAX_SYMBOL_SIZE 1024
......
......@@ -28,7 +28,7 @@
#include <libunwind.h>
#endif
#if FOLLY_USE_SYMBOLIZER
#if FOLLY_HAVE_BACKTRACE
#include <execinfo.h>
#endif
......@@ -54,7 +54,7 @@ ssize_t getStackTrace(
#if FOLLY_HAVE_LIBUNWIND && defined(UNW_VERSION)
int r = unw_backtrace(reinterpret_cast<void**>(addresses), maxAddresses);
return r < 0 ? -1 : r;
#elif FOLLY_USE_SYMBOLIZER
#elif FOLLY_HAVE_BACKTRACE
int r = backtrace(reinterpret_cast<void**>(addresses), maxAddresses);
return r < 0 ? -1 : r;
#else
......
......@@ -35,6 +35,10 @@
#include <folly/portability/SysMman.h>
#include <folly/portability/Unistd.h>
#if FOLLY_HAVE_BACKTRACE
#include <execinfo.h>
#endif
#if FOLLY_HAVE_ELF
#include <link.h>
#include <ucontext.h>
......@@ -271,6 +275,27 @@ void SafeStackTracePrinter::printSymbolizedStackTrace() {
printer_.println(*addresses_, 2);
}
void SafeStackTracePrinter::printUnsymbolizedStackTrace() {
print("(safe mode, symbolizer not available)\n");
#if FOLLY_HAVE_BACKTRACE
// `backtrace_symbols_fd` from execinfo.h is not explicitly
// documented on either macOS or Linux to be async-signal-safe, but
// the implementation in
// https://opensource.apple.com/source/Libc/Libc-1353.60.8/ appears
// safe.
::backtrace_symbols_fd(
reinterpret_cast<void**>(addresses_->addresses),
addresses_->frameCount,
fd_);
#else
AddressFormatter formatter;
for (size_t i = 0; i < addresses_->frameCount; ++i) {
print(formatter.format(addresses_->addresses[i]));
print("\n");
}
#endif
}
void SafeStackTracePrinter::printStackTrace(bool symbolize) {
SCOPE_EXIT {
flush();
......@@ -282,12 +307,7 @@ void SafeStackTracePrinter::printStackTrace(bool symbolize) {
} else if (symbolize) {
printSymbolizedStackTrace();
} else {
print("(safe mode, symbolizer not available)\n");
AddressFormatter formatter;
for (size_t i = 0; i < addresses_->frameCount; ++i) {
print(formatter.format(addresses_->addresses[i]));
print("\n");
}
printUnsymbolizedStackTrace();
}
}
......
......@@ -196,6 +196,7 @@ class SafeStackTracePrinter {
protected:
virtual void printSymbolizedStackTrace();
void printUnsymbolizedStackTrace();
private:
static constexpr size_t kMaxStackTraceDepth = 100;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment