Expose folly::symbolizer::dumpStackTrace().
[folly.git] / folly / experimental / symbolizer / Symbolizer.h
index bd93c121f42195fe62aa2057991cd951797a3659..9ce617b071a6d0ae3783813ba3a0321a99f810f1 100644 (file)
@@ -307,5 +307,46 @@ class StringSymbolizePrinter : public SymbolizePrinter {
   fbstring buf_;
 };
 
+/**
+ * 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 constructo 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.
+ */
+class StackTracePrinter {
+ public:
+  static constexpr size_t kDefaultMinSignalSafeElfCacheSize = 500;
+  explicit StackTracePrinter(
+      size_t minSignalSafeElfCacheSize = kDefaultMinSignalSafeElfCacheSize,
+      int fd = STDERR_FILENO);
+
+  /**
+   * 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.
+   */
+  FOLLY_NOINLINE void printStackTrace(bool symbolize);
+
+  void print(StringPiece sp) {
+    printer_.print(sp);
+  }
+
+  // Flush printer_, also fsync, in case we're about to crash again...
+  void flush();
+
+ private:
+  int fd_;
+  SignalSafeElfCache elfCache_;
+  FDSymbolizePrinter printer_;
+};
+
 }  // namespace symbolizer
 }  // namespace folly