proxygen
folly::symbolizer Namespace Reference

Namespaces

 detail
 
 test
 

Classes

class  AddressFormatter
 
class  Dwarf
 
class  ElfCache
 
class  ElfCacheBase
 
class  ElfFile
 
class  FastStackTracePrinter
 
class  FDSymbolizePrinter
 
class  FILESymbolizePrinter
 
struct  FrameArray
 
class  LineReader
 
class  OStreamSymbolizePrinter
 
class  SafeStackTracePrinter
 
class  SignalSafeElfCache
 
class  StringSymbolizePrinter
 
struct  SymbolizedFrame
 
class  SymbolizePrinter
 
class  Symbolizer
 
class  UnsafeSelfAllocateStackTracePrinter
 

Typedefs

using ElfAddr = ElfW(Addr)
 
using ElfEhdr = ElfW(Ehdr)
 
using ElfOff = ElfW(Off)
 
using ElfPhdr = ElfW(Phdr)
 
using ElfShdr = ElfW(Shdr)
 
using ElfSym = ElfW(Sym)
 
typedef void(* SignalCallback) ()
 

Functions

std::ostream & operator<< (std::ostream &out, const Dwarf::Path &path)
 
size_t countLoadedElfFiles ()
 
void addFatalSignalCallback (SignalCallback cb)
 
void installFatalSignalCallbacks ()
 
void installFatalSignalHandler ()
 
ssize_t getStackTrace (uintptr_t *addresses, size_t maxAddresses)
 
ssize_t getStackTraceSafe (uintptr_t *addresses, size_t maxAddresses)
 
template<size_t N>
FOLLY_ALWAYS_INLINE bool getStackTrace (FrameArray< N > &fa)
 
template<size_t N>
bool getStackTrace (FrameArray< N > &fa)
 
template<size_t N>
FOLLY_ALWAYS_INLINE bool getStackTraceSafe (FrameArray< N > &fa)
 
template<size_t N>
bool getStackTraceSafe (FrameArray< N > &fa)
 

Typedef Documentation

using folly::symbolizer::ElfAddr = typedef ElfW(Addr)

Definition at line 38 of file Elf.h.

using folly::symbolizer::ElfEhdr = typedef ElfW(Ehdr)

Definition at line 39 of file Elf.h.

using folly::symbolizer::ElfOff = typedef ElfW(Off)

Definition at line 40 of file Elf.h.

using folly::symbolizer::ElfPhdr = typedef ElfW(Phdr)

Definition at line 41 of file Elf.h.

using folly::symbolizer::ElfShdr = typedef ElfW(Shdr)

Definition at line 42 of file Elf.h.

using folly::symbolizer::ElfSym = typedef ElfW(Sym)

Definition at line 43 of file Elf.h.

typedef void(* folly::symbolizer::SignalCallback) ()

Add a callback to be run when receiving a fatal signal. They will also be called by LOG(FATAL) and abort() (as those raise SIGABRT internally).

These callbacks must be async-signal-safe, so don't even think of using LOG(...) or printf or malloc / new or doing anything even remotely fun.

All these fatal callback must be added before calling installFatalSignalCallbacks(), below.

Definition at line 43 of file SignalHandler.h.

Function Documentation

void folly::symbolizer::addFatalSignalCallback ( SignalCallback  cb)

Definition at line 438 of file SignalHandler.cpp.

Referenced by folly::symbolizer::test::TEST().

438  {
439  gFatalSignalCallbackRegistry->add(cb);
440 }
size_t folly::symbolizer::countLoadedElfFiles ( )

Number of ELF files loaded by the dynamic loader.

Definition at line 32 of file ElfCache.cpp.

References _r_debug, and count.

Referenced by folly::symbolizer::FastStackTracePrinter::FastStackTracePrinter().

32  {
33  // _r_debug synchronization is... lacking to say the least. It's
34  // meant as an aid for debuggers and synchronization is done by
35  // calling dl_debug_state() which debuggers are supposed to
36  // intercept by setting a breakpoint on.
37 
38  // Can't really do that here, so we apply the hope-and-pray strategy.
39  if (_r_debug.r_version != 1 || _r_debug.r_state != r_debug::RT_CONSISTENT) {
40  // computo ergo sum
41  return 1;
42  }
43 
44  // r_map -> head of a linked list of 'link_map_t' entries,
45  // one per ELF 'binary' in the process address space.
46  size_t count = 0;
47  for (auto lmap = _r_debug.r_map; lmap != nullptr; lmap = lmap->l_next) {
48  ++count;
49  }
50  return count;
51 }
struct r_debug _r_debug
int * count
ssize_t folly::symbolizer::getStackTrace ( uintptr_t *  addresses,
size_t  maxAddresses 
)

Get the current stack trace into addresses, which has room for at least maxAddresses frames.

Returns the number of frames written in the array. Returns -1 on failure.

NOT async-signal-safe, but fast.

Definition at line 25 of file StackTrace.cpp.

Referenced by folly::symbolizer::test::comparator(), folly::symbolizer::detail::fixFrameArray(), getStackTrace(), folly::exception_tracer::operator<<(), folly::exception_tracer::StackTraceStack::pushCurrent(), and verifyStackTraces().

25  {
26  static_assert(
27  sizeof(uintptr_t) == sizeof(void*), "uintptr_t / pointer size mismatch");
28  // The libunwind documentation says that unw_backtrace is async-signal-safe
29  // but, as of libunwind 1.0.1, it isn't (tdep_trace allocates memory on
30  // x86_64)
31  int r = unw_backtrace(reinterpret_cast<void**>(addresses), maxAddresses);
32  return r < 0 ? -1 : r;
33 }
template<size_t N>
FOLLY_ALWAYS_INLINE bool folly::symbolizer::getStackTrace ( FrameArray< N > &  fa)
inline

Definition at line 107 of file Symbolizer.h.

References folly::symbolizer::FrameArray< N >::addresses, folly::symbolizer::detail::fixFrameArray(), FOLLY_ALWAYS_INLINE, getStackTrace(), and getStackTraceSafe().

107  {
108  return detail::fixFrameArray(fa, getStackTrace(fa.addresses, N));
109 }
bool fixFrameArray(FrameArray< N > &fa, ssize_t n)
Definition: Symbolizer.h:87
bool getStackTrace(FrameArray< N > &fa)
Definition: Symbolizer.h:107
template<size_t N>
bool folly::symbolizer::getStackTrace ( FrameArray< N > &  fa)
inline

Definition at line 107 of file Symbolizer.h.

References folly::symbolizer::FrameArray< N >::addresses, folly::symbolizer::detail::fixFrameArray(), FOLLY_ALWAYS_INLINE, getStackTrace(), and getStackTraceSafe().

107  {
108  return detail::fixFrameArray(fa, getStackTrace(fa.addresses, N));
109 }
bool fixFrameArray(FrameArray< N > &fa, ssize_t n)
Definition: Symbolizer.h:87
bool getStackTrace(FrameArray< N > &fa)
Definition: Symbolizer.h:107
ssize_t folly::symbolizer::getStackTraceSafe ( uintptr_t *  addresses,
size_t  maxAddresses 
)

Get the current stack trace into addresses, which has room for at least maxAddresses frames.

Returns the number of frames written in the array. Returns -1 on failure.

Async-signal-safe, but likely slower.

Definition at line 53 of file StackTrace.cpp.

References context, and count.

Referenced by getStackTrace(), getStackTraceSafe(), folly::symbolizer::SafeStackTracePrinter::printStackTrace(), folly::symbolizer::FastStackTracePrinter::printStackTrace(), folly::SingletonVault::scheduleDestroyInstances(), and verifyStackTraces().

53  {
54  if (maxAddresses == 0) {
55  return 0;
56  }
57  unw_context_t context;
58  if (unw_getcontext(&context) < 0) {
59  return -1;
60  }
61  unw_cursor_t cursor;
62  if (unw_init_local(&cursor, &context) < 0) {
63  return -1;
64  }
65  if (!getFrameInfo(&cursor, *addresses)) {
66  return -1;
67  }
68  ++addresses;
69  size_t count = 1;
70  for (; count != maxAddresses; ++count, ++addresses) {
71  int r = unw_step(&cursor);
72  if (r < 0) {
73  return -1;
74  }
75  if (r == 0) {
76  break;
77  }
78  if (!getFrameInfo(&cursor, *addresses)) {
79  return -1;
80  }
81  }
82  return count;
83 }
context
Definition: CMakeCache.txt:563
int * count
template<size_t N>
FOLLY_ALWAYS_INLINE bool folly::symbolizer::getStackTraceSafe ( FrameArray< N > &  fa)
inline

Definition at line 114 of file Symbolizer.h.

References folly::symbolizer::FrameArray< N >::addresses, folly::symbolizer::detail::fixFrameArray(), and getStackTraceSafe().

114  {
115  return detail::fixFrameArray(fa, getStackTraceSafe(fa.addresses, N));
116 }
bool getStackTraceSafe(FrameArray< N > &fa)
Definition: Symbolizer.h:114
bool fixFrameArray(FrameArray< N > &fa, ssize_t n)
Definition: Symbolizer.h:87
template<size_t N>
bool folly::symbolizer::getStackTraceSafe ( FrameArray< N > &  fa)
inline

Definition at line 114 of file Symbolizer.h.

References folly::symbolizer::FrameArray< N >::addresses, folly::symbolizer::detail::fixFrameArray(), and getStackTraceSafe().

114  {
115  return detail::fixFrameArray(fa, getStackTraceSafe(fa.addresses, N));
116 }
bool getStackTraceSafe(FrameArray< N > &fa)
Definition: Symbolizer.h:114
bool fixFrameArray(FrameArray< N > &fa, ssize_t n)
Definition: Symbolizer.h:87
void folly::symbolizer::installFatalSignalCallbacks ( )

Install the fatal signal callbacks; fatal signals will call these callbacks in the order in which they were added.

Definition at line 442 of file SignalHandler.cpp.

Referenced by folly::init(), and folly::symbolizer::test::TEST().

442  {
443  gFatalSignalCallbackRegistry->markInstalled();
444 }
void folly::symbolizer::installFatalSignalHandler ( )

Install handler for fatal signals. The list of signals being handled is in SignalHandler.cpp.

The handler will dump signal and time information followed by a stack trace to stderr, and then call the callbacks registered below.

Definition at line 468 of file SignalHandler.cpp.

Referenced by folly::init(), main(), and folly::symbolizer::test::TEST().

468  {
469  if (gAlreadyInstalled.exchange(true)) {
470  // Already done.
471  return;
472  }
473 
474  // If a small sigaltstack is enabled (ex. Rust stdlib might use sigaltstack
475  // to set a small stack), the default SafeStackTracePrinter would likely
476  // stack overflow. Replace it with the unsafe self-allocate printer.
477  bool useUnsafePrinter = isSmallSigAltStackEnabled();
478  if (useUnsafePrinter) {
479  gStackTracePrinter = new UnsafeSelfAllocateStackTracePrinter();
480  } else {
481  gStackTracePrinter = new SafeStackTracePrinter();
482  }
483 
484  struct sigaction sa;
485  memset(&sa, 0, sizeof(sa));
486  if (useUnsafePrinter) {
487  // The signal handler is not async-signal-safe. Block all signals to
488  // make it safer. But it's still unsafe.
489  sigfillset(&sa.sa_mask);
490  } else {
491  sigemptyset(&sa.sa_mask);
492  }
493  // By default signal handlers are run on the signaled thread's stack.
494  // In case of stack overflow running the SIGSEGV signal handler on
495  // the same stack leads to another SIGSEGV and crashes the program.
496  // Use SA_ONSTACK, so alternate stack is used (only if configured via
497  // sigaltstack).
498  // Golang also requires SA_ONSTACK. See:
499  // https://golang.org/pkg/os/signal/#hdr-Go_programs_that_use_cgo_or_SWIG
500  sa.sa_flags |= SA_SIGINFO | SA_ONSTACK;
501  sa.sa_sigaction = &signalHandler;
502 
503  for (auto p = kFatalSignals; p->name; ++p) {
504  CHECK_ERR(sigaction(p->number, &sa, &p->oldAction));
505  }
506 }
std::ostream& folly::symbolizer::operator<< ( std::ostream &  out,
const Dwarf::Path path 
)
inline

Definition at line 292 of file Dwarf.h.

References folly::symbolizer::Dwarf::Path::toString().

292  {
293  return out << path.toString();
294 }