fall back to .debug_info scan in fatal signal handler
[folly.git] / folly / experimental / symbolizer / SignalHandler.cpp
index 7719c5d4640a24f85b06dfddedd5040ff4f45f0b..06173c08f2be89d997f0e22fcc40fafe349158e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #include <folly/experimental/symbolizer/SignalHandler.h>
 
+#include <pthread.h>
+#include <signal.h>
 #include <sys/types.h>
-#include <sys/syscall.h>
+#include <unistd.h>
+
+#include <algorithm>
 #include <atomic>
 #include <ctime>
 #include <mutex>
-#include <pthread.h>
-#include <signal.h>
-#include <unistd.h>
 #include <vector>
 
 #include <glog/logging.h>
@@ -34,7 +35,9 @@
 #include <folly/FileUtil.h>
 #include <folly/Portability.h>
 #include <folly/ScopeGuard.h>
+#include <folly/experimental/symbolizer/ElfCache.h>
 #include <folly/experimental/symbolizer/Symbolizer.h>
+#include <folly/portability/SysSyscall.h>
 
 namespace folly { namespace symbolizer {
 
@@ -95,13 +98,13 @@ struct {
   const char* name;
   struct sigaction oldAction;
 } kFatalSignals[] = {
-  { SIGSEGV, "SIGSEGV" },
-  { SIGILL,  "SIGILL"  },
-  { SIGFPE,  "SIGFPE"  },
-  { SIGABRT, "SIGABRT" },
-  { SIGBUS,  "SIGBUS"  },
-  { SIGTERM, "SIGTERM" },
-  { 0,       nullptr   }
+  { SIGSEGV, "SIGSEGV", {} },
+  { SIGILL,  "SIGILL",  {} },
+  { SIGFPE,  "SIGFPE",  {} },
+  { SIGABRT, "SIGABRT", {} },
+  { SIGBUS,  "SIGBUS",  {} },
+  { SIGTERM, "SIGTERM", {} },
+  { 0,       nullptr,   {} }
 };
 
 void callPreviousSignalHandler(int signum) {
@@ -124,13 +127,13 @@ void callPreviousSignalHandler(int signum) {
   raise(signum);
 }
 
-constexpr size_t kDefaultCapacity = 500;
-
 // Note: not thread-safe, but that's okay, as we only let one thread
 // in our signal handler at a time.
 //
 // Leak it so we don't have to worry about destruction order
-auto gSignalSafeElfCache = new SignalSafeElfCache(kDefaultCapacity);
+constexpr size_t kMinSignalSafeElfCacheSize = 500;
+auto gSignalSafeElfCache = new SignalSafeElfCache(
+    std::max(countLoadedElfFiles(), kMinSignalSafeElfCacheSize));
 
 // Buffered writer (using a fixed-size buffer). We try to write only once
 // to prevent interleaving with messages written from other threads.
@@ -393,7 +396,9 @@ void dumpStackTrace(bool symbolize) {
   if (!getStackTraceSafe(addresses)) {
     print("(error retrieving stack trace)\n");
   } else if (symbolize) {
-    Symbolizer symbolizer(gSignalSafeElfCache);
+    // Do our best to populate location info, process is going to terminate,
+    // so performance isn't critical.
+    Symbolizer symbolizer(gSignalSafeElfCache, Dwarf::LocationInfoMode::FULL);
     symbolizer.symbolize(addresses);
 
     // Skip the top 2 frames: