proxygen
folly::symbolizer::SafeStackTracePrinter Class Reference

#include <Symbolizer.h>

Inheritance diagram for folly::symbolizer::SafeStackTracePrinter:
folly::symbolizer::UnsafeSelfAllocateStackTracePrinter

Public Member Functions

 SafeStackTracePrinter (size_t minSignalSafeElfCacheSize=kDefaultMinSignalSafeElfCacheSize, int fd=STDERR_FILENO)
 
virtual ~SafeStackTracePrinter ()
 
FOLLY_NOINLINE void printStackTrace (bool symbolize)
 
void print (StringPiece sp)
 
void flush ()
 

Static Public Attributes

static constexpr size_t kDefaultMinSignalSafeElfCacheSize = 500
 

Protected Member Functions

virtual void printSymbolizedStackTrace ()
 

Private Attributes

int fd_
 
SignalSafeElfCache elfCache_
 
FDSymbolizePrinter printer_
 
std::unique_ptr< FrameArray< kMaxStackTraceDepth > > addresses_
 

Static Private Attributes

static constexpr size_t kMaxStackTraceDepth = 100
 

Detailed Description

Use this class to print a stack trace from a signal handler, or other place where you shouldn't allocate memory on the heap, and fsync()ing your file descriptor is more important than performance.

Make sure to create one of these on startup, not in the signal handler, as the constructor allocates on the heap, whereas the other methods don't. Best practice is to just leak this object, rather than worry about destruction order.

These methods aren't thread safe, so if you could have signals on multiple threads at the same time, you need to do your own locking to ensure you don't call these methods from multiple threads. They are signal safe, however.

Definition at line 351 of file Symbolizer.h.

Constructor & Destructor Documentation

folly::symbolizer::SafeStackTracePrinter::SafeStackTracePrinter ( size_t  minSignalSafeElfCacheSize = kDefaultMinSignalSafeElfCacheSize,
int  fd = STDERR_FILENO 
)
explicit

Definition at line 409 of file Symbolizer.cpp.

412  : fd_(fd),
413  elfCache_(std::max(countLoadedElfFiles(), minSignalSafeElfCacheSize)),
414  printer_(
415  fd,
417  size_t(64) << 10), // 64KiB
418  addresses_(std::make_unique<FrameArray<kMaxStackTraceDepth>>()) {}
LogLevel max
Definition: LogLevel.cpp:31
size_t countLoadedElfFiles()
Definition: ElfCache.cpp:32
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Definition: Memory.h:259
std::unique_ptr< FrameArray< kMaxStackTraceDepth > > addresses_
Definition: Symbolizer.h:387
virtual folly::symbolizer::SafeStackTracePrinter::~SafeStackTracePrinter ( )
inlinevirtual

Definition at line 359 of file Symbolizer.h.

References FOLLY_NOINLINE.

359 {}

Member Function Documentation

void folly::symbolizer::SafeStackTracePrinter::flush ( )

Definition at line 420 of file Symbolizer.cpp.

References fd_, folly::symbolizer::FDSymbolizePrinter::flush(), folly::fsyncNoInt(), and printer_.

Referenced by printStackTrace().

420  {
421  printer_.flush();
422  fsyncNoInt(fd_);
423 }
int fsyncNoInt(int fd)
Definition: FileUtil.cpp:64
void folly::symbolizer::SafeStackTracePrinter::print ( StringPiece  sp)
inline

Definition at line 371 of file Symbolizer.h.

Referenced by printStackTrace().

371  {
372  printer_.print(sp);
373  }
void print(uintptr_t address, const SymbolizedFrame &frame)
Definition: Symbolizer.cpp:208
void folly::symbolizer::SafeStackTracePrinter::printStackTrace ( bool  symbolize)

Only allocates on the stack and is signal-safe but not thread-safe. Don't call printStackTrace() on the same StackTracePrinter object from multiple threads at the same time.

This is NOINLINE to make sure it shows up in the stack we grab, which makes it easy to skip printing it.

Definition at line 443 of file Symbolizer.cpp.

References addresses_, flush(), folly::symbolizer::AddressFormatter::format(), folly::symbolizer::getStackTraceSafe(), i, print(), printSymbolizedStackTrace(), and SCOPE_EXIT.

443  {
444  SCOPE_EXIT {
445  flush();
446  };
447 
448  // Skip the getStackTrace frame
449  if (!getStackTraceSafe(*addresses_)) {
450  print("(error retrieving stack trace)\n");
451  } else if (symbolize) {
453  } else {
454  print("(safe mode, symbolizer not available)\n");
455  AddressFormatter formatter;
456  for (size_t i = 0; i < addresses_->frameCount; ++i) {
457  print(formatter.format(addresses_->addresses[i]));
458  print("\n");
459  }
460  }
461 }
ssize_t getStackTraceSafe(uintptr_t *addresses, size_t maxAddresses)
Definition: StackTrace.cpp:53
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
std::unique_ptr< FrameArray< kMaxStackTraceDepth > > addresses_
Definition: Symbolizer.h:387
void folly::symbolizer::SafeStackTracePrinter::printSymbolizedStackTrace ( )
protectedvirtual

Reimplemented in folly::symbolizer::UnsafeSelfAllocateStackTracePrinter.

Definition at line 425 of file Symbolizer.cpp.

References addresses_, elfCache_, folly::symbolizer::Dwarf::FULL, printer_, folly::symbolizer::SymbolizePrinter::println(), and folly::symbolizer::Symbolizer::symbolize().

Referenced by printStackTrace().

425  {
426  // This function might run on an alternative stack allocated by
427  // UnsafeSelfAllocateStackTracePrinter. Capturing a stack from
428  // here is probably wrong.
429 
430  // Do our best to populate location info, process is going to terminate,
431  // so performance isn't critical.
432  Symbolizer symbolizer(&elfCache_, Dwarf::LocationInfoMode::FULL);
433  symbolizer.symbolize(*addresses_);
434 
435  // Skip the top 2 frames captured by printStackTrace:
436  // getStackTraceSafe
437  // SafeStackTracePrinter::printStackTrace (captured stack)
438  //
439  // Leaving signalHandler on the stack for clarity, I think.
441 }
void println(uintptr_t address, const SymbolizedFrame &frame)
Definition: Symbolizer.cpp:284
std::unique_ptr< FrameArray< kMaxStackTraceDepth > > addresses_
Definition: Symbolizer.h:387

Member Data Documentation

std::unique_ptr<FrameArray<kMaxStackTraceDepth> > folly::symbolizer::SafeStackTracePrinter::addresses_
private

Definition at line 387 of file Symbolizer.h.

Referenced by printStackTrace(), and printSymbolizedStackTrace().

SignalSafeElfCache folly::symbolizer::SafeStackTracePrinter::elfCache_
private

Definition at line 385 of file Symbolizer.h.

Referenced by printSymbolizedStackTrace().

int folly::symbolizer::SafeStackTracePrinter::fd_
private

Definition at line 384 of file Symbolizer.h.

Referenced by flush().

constexpr size_t folly::symbolizer::SafeStackTracePrinter::kDefaultMinSignalSafeElfCacheSize = 500
static

Definition at line 353 of file Symbolizer.h.

constexpr size_t folly::symbolizer::SafeStackTracePrinter::kMaxStackTraceDepth = 100
staticprivate

Definition at line 382 of file Symbolizer.h.

FDSymbolizePrinter folly::symbolizer::SafeStackTracePrinter::printer_
private

Definition at line 386 of file Symbolizer.h.

Referenced by flush(), and printSymbolizedStackTrace().


The documentation for this class was generated from the following files: