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 @@ ...@@ -70,6 +70,7 @@
#cmakedefine FOLLY_HAVE_LIBUNWIND 1 #cmakedefine FOLLY_HAVE_LIBUNWIND 1
#cmakedefine FOLLY_HAVE_DWARF 1 #cmakedefine FOLLY_HAVE_DWARF 1
#cmakedefine FOLLY_HAVE_ELF 1 #cmakedefine FOLLY_HAVE_ELF 1
#cmakedefine FOLLY_HAVE_BACKTRACE 1
#cmakedefine FOLLY_USE_SYMBOLIZER 1 #cmakedefine FOLLY_USE_SYMBOLIZER 1
#define FOLLY_DEMANGLE_MAX_SYMBOL_SIZE 1024 #define FOLLY_DEMANGLE_MAX_SYMBOL_SIZE 1024
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <libunwind.h> #include <libunwind.h>
#endif #endif
#if FOLLY_USE_SYMBOLIZER #if FOLLY_HAVE_BACKTRACE
#include <execinfo.h> #include <execinfo.h>
#endif #endif
...@@ -54,7 +54,7 @@ ssize_t getStackTrace( ...@@ -54,7 +54,7 @@ ssize_t getStackTrace(
#if FOLLY_HAVE_LIBUNWIND && defined(UNW_VERSION) #if FOLLY_HAVE_LIBUNWIND && defined(UNW_VERSION)
int r = unw_backtrace(reinterpret_cast<void**>(addresses), maxAddresses); int r = unw_backtrace(reinterpret_cast<void**>(addresses), maxAddresses);
return r < 0 ? -1 : r; return r < 0 ? -1 : r;
#elif FOLLY_USE_SYMBOLIZER #elif FOLLY_HAVE_BACKTRACE
int r = backtrace(reinterpret_cast<void**>(addresses), maxAddresses); int r = backtrace(reinterpret_cast<void**>(addresses), maxAddresses);
return r < 0 ? -1 : r; return r < 0 ? -1 : r;
#else #else
......
...@@ -35,6 +35,10 @@ ...@@ -35,6 +35,10 @@
#include <folly/portability/SysMman.h> #include <folly/portability/SysMman.h>
#include <folly/portability/Unistd.h> #include <folly/portability/Unistd.h>
#if FOLLY_HAVE_BACKTRACE
#include <execinfo.h>
#endif
#if FOLLY_HAVE_ELF #if FOLLY_HAVE_ELF
#include <link.h> #include <link.h>
#include <ucontext.h> #include <ucontext.h>
...@@ -271,6 +275,27 @@ void SafeStackTracePrinter::printSymbolizedStackTrace() { ...@@ -271,6 +275,27 @@ void SafeStackTracePrinter::printSymbolizedStackTrace() {
printer_.println(*addresses_, 2); 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) { void SafeStackTracePrinter::printStackTrace(bool symbolize) {
SCOPE_EXIT { SCOPE_EXIT {
flush(); flush();
...@@ -282,12 +307,7 @@ void SafeStackTracePrinter::printStackTrace(bool symbolize) { ...@@ -282,12 +307,7 @@ void SafeStackTracePrinter::printStackTrace(bool symbolize) {
} else if (symbolize) { } else if (symbolize) {
printSymbolizedStackTrace(); printSymbolizedStackTrace();
} else { } else {
print("(safe mode, symbolizer not available)\n"); printUnsymbolizedStackTrace();
AddressFormatter formatter;
for (size_t i = 0; i < addresses_->frameCount; ++i) {
print(formatter.format(addresses_->addresses[i]));
print("\n");
}
} }
} }
......
...@@ -196,6 +196,7 @@ class SafeStackTracePrinter { ...@@ -196,6 +196,7 @@ class SafeStackTracePrinter {
protected: protected:
virtual void printSymbolizedStackTrace(); virtual void printSymbolizedStackTrace();
void printUnsymbolizedStackTrace();
private: private:
static constexpr size_t kMaxStackTraceDepth = 100; 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