Make Singleton dependency on Symbolizer Facebook-only
authorAndrii Grynenko <andrii@fb.com>
Wed, 11 Feb 2015 21:41:55 +0000 (13:41 -0800)
committerSara Golemon <sgolemon@fb.com>
Thu, 12 Feb 2015 16:55:08 +0000 (08:55 -0800)
Summary: Open-source build was broken because Symbolizer is not part of it.

Test Plan: singleton unit test w/ and w/o SingletonStackTrace.cpp linked in.

Reviewed By: alikhtarov@fb.com

Subscribers: trunkagent, folly-diffs@, yfeldblum

FB internal diff: D1840346

Signature: t1:1840346:1423690004:926c2aa21e0b7916260749120997ad56fab6f742

folly/experimental/Singleton-inl.h
folly/experimental/Singleton.h
folly/experimental/SingletonStackTrace.cpp [new file with mode: 0644]

index 45e112dd95448e6d0139dce6afb3ba43737cae6f..ac515db414d785e18c5a9014e7ea090c40b96958 100644 (file)
@@ -158,23 +158,13 @@ void SingletonHolder<T>::createInstance() {
       if (print_destructor_stack_trace->load()) {
         std::string output = "Singleton " + type_name + " was destroyed.\n";
 
-        // Get and symbolize stack trace
-        constexpr size_t kMaxStackTraceDepth = 100;
-        symbolizer::FrameArray<kMaxStackTraceDepth> addresses;
-        if (!getStackTraceSafe(addresses)) {
+        auto stack_trace_getter = SingletonVault::stackTraceGetter().load();
+        auto stack_trace = stack_trace_getter ? stack_trace_getter() : "";
+        if (stack_trace.empty()) {
           output += "Failed to get destructor stack trace.";
         } else {
           output += "Destructor stack trace:\n";
-
-          constexpr size_t kDefaultCapacity = 500;
-          symbolizer::ElfCache elfCache(kDefaultCapacity);
-
-          symbolizer::Symbolizer symbolizer(&elfCache);
-          symbolizer.symbolize(addresses);
-
-          symbolizer::StringSymbolizePrinter printer;
-          printer.println(addresses);
-          output += printer.str();
+          output += stack_trace;
         }
 
         LOG(ERROR) << output;
index a5437a39735f3267c1cc9ec12facba3e98cacfb4..6ad4d4286a1963d507eb61753c99c0208087d013 100644 (file)
@@ -375,6 +375,13 @@ class SingletonVault {
     return vault;
   }
 
+  typedef std::string(*StackTraceGetterPtr)();
+
+  static std::atomic<StackTraceGetterPtr>& stackTraceGetter() {
+    static std::atomic<StackTraceGetterPtr> stackTraceGetterPtr;
+    return stackTraceGetterPtr;
+  }
+
  private:
   template <typename T>
   friend class detail::SingletonHolder;
diff --git a/folly/experimental/SingletonStackTrace.cpp b/folly/experimental/SingletonStackTrace.cpp
new file mode 100644 (file)
index 0000000..da53574
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <folly/experimental/Singleton.h>
+#include <folly/experimental/symbolizer/Symbolizer.h>
+
+namespace folly {
+
+namespace {
+
+std::string stackTraceGetter() {
+  // Get and symbolize stack trace
+  constexpr size_t kMaxStackTraceDepth = 100;
+  symbolizer::FrameArray<kMaxStackTraceDepth> addresses;
+
+  if (!getStackTraceSafe(addresses)) {
+    return "";
+  } else {
+    constexpr size_t kDefaultCapacity = 500;
+    symbolizer::ElfCache elfCache(kDefaultCapacity);
+
+    symbolizer::Symbolizer symbolizer(&elfCache);
+    symbolizer.symbolize(addresses);
+
+    symbolizer::StringSymbolizePrinter printer;
+    printer.println(addresses);
+    return printer.str();
+  }
+}
+
+struct SetStackTraceGetter {
+  SetStackTraceGetter() {
+    SingletonVault::stackTraceGetter().store(stackTraceGetter);
+  }
+};
+
+SetStackTraceGetter setStackTraceGetter;
+
+}
+
+}