From 01734a1ca5c48f991618b53fa2bf0b9dda070362 Mon Sep 17 00:00:00 2001 From: Andrii Grynenko Date: Wed, 11 Feb 2015 13:41:55 -0800 Subject: [PATCH] Make Singleton dependency on Symbolizer Facebook-only 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 | 18 ++------ folly/experimental/Singleton.h | 7 +++ folly/experimental/SingletonStackTrace.cpp | 53 ++++++++++++++++++++++ 3 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 folly/experimental/SingletonStackTrace.cpp diff --git a/folly/experimental/Singleton-inl.h b/folly/experimental/Singleton-inl.h index 45e112dd..ac515db4 100644 --- a/folly/experimental/Singleton-inl.h +++ b/folly/experimental/Singleton-inl.h @@ -158,23 +158,13 @@ void SingletonHolder::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 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; diff --git a/folly/experimental/Singleton.h b/folly/experimental/Singleton.h index a5437a39..6ad4d428 100644 --- a/folly/experimental/Singleton.h +++ b/folly/experimental/Singleton.h @@ -375,6 +375,13 @@ class SingletonVault { return vault; } + typedef std::string(*StackTraceGetterPtr)(); + + static std::atomic& stackTraceGetter() { + static std::atomic stackTraceGetterPtr; + return stackTraceGetterPtr; + } + private: template friend class detail::SingletonHolder; diff --git a/folly/experimental/SingletonStackTrace.cpp b/folly/experimental/SingletonStackTrace.cpp new file mode 100644 index 00000000..da535743 --- /dev/null +++ b/folly/experimental/SingletonStackTrace.cpp @@ -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 +#include + +namespace folly { + +namespace { + +std::string stackTraceGetter() { + // Get and symbolize stack trace + constexpr size_t kMaxStackTraceDepth = 100; + symbolizer::FrameArray 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; + +} + +} -- 2.34.1