Commit 886ed94b authored by Kenny Yu's avatar Kenny Yu Committed by Facebook GitHub Bot

delete detail::getSingletonStackTrace

Summary: This removes `detail::getSingletonStackTrace` in favor of `symbolizer::getStackTraceStr`.

Reviewed By: yfeldblum

Differential Revision: D33783970

fbshipit-source-id: 416ff70abb79ce4e9c3180c0872432ae2966effc
parent 9adda7dd
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <folly/Demangle.h> #include <folly/Demangle.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/detail/SingletonStackTrace.h> #include <folly/experimental/symbolizer/Symbolizer.h>
#include <folly/portability/Config.h> #include <folly/portability/Config.h>
#include <folly/portability/FmtCompile.h> #include <folly/portability/FmtCompile.h>
...@@ -97,7 +97,7 @@ std::string TypeDescriptor::name() const { ...@@ -97,7 +97,7 @@ std::string TypeDescriptor::name() const {
[[noreturn]] void singletonWarnLeakyInstantiatingNotRegisteredAndAbort( [[noreturn]] void singletonWarnLeakyInstantiatingNotRegisteredAndAbort(
const TypeDescriptor& type) { const TypeDescriptor& type) {
auto trace = detail::getSingletonStackTrace(); auto trace = symbolizer::getStackTraceStr();
LOG(FATAL) << "Creating instance for unregistered singleton: " << type.name() LOG(FATAL) << "Creating instance for unregistered singleton: " << type.name()
<< "\n" << "\n"
<< "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)"); << "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)");
...@@ -132,7 +132,7 @@ void singletonWarnDestroyInstanceLeak( ...@@ -132,7 +132,7 @@ void singletonWarnDestroyInstanceLeak(
[[noreturn]] void singletonWarnCreateUnregisteredAndAbort( [[noreturn]] void singletonWarnCreateUnregisteredAndAbort(
const TypeDescriptor& type) { const TypeDescriptor& type) {
auto trace = detail::getSingletonStackTrace(); auto trace = symbolizer::getStackTraceStr();
LOG(FATAL) << "Creating instance for unregistered singleton: " << type.name() LOG(FATAL) << "Creating instance for unregistered singleton: " << type.name()
<< "\n" << "\n"
<< "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)"); << "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)");
...@@ -141,7 +141,7 @@ void singletonWarnDestroyInstanceLeak( ...@@ -141,7 +141,7 @@ void singletonWarnDestroyInstanceLeak(
[[noreturn]] void singletonWarnCreateBeforeRegistrationCompleteAndAbort( [[noreturn]] void singletonWarnCreateBeforeRegistrationCompleteAndAbort(
const TypeDescriptor& type) { const TypeDescriptor& type) {
auto trace = detail::getSingletonStackTrace(); auto trace = symbolizer::getStackTraceStr();
LOG(FATAL) << "Singleton " << type.name() << " requested before " LOG(FATAL) << "Singleton " << type.name() << " requested before "
<< "registrationComplete() call.\n" << "registrationComplete() call.\n"
<< "This usually means that either main() never called " << "This usually means that either main() never called "
...@@ -152,7 +152,7 @@ void singletonWarnDestroyInstanceLeak( ...@@ -152,7 +152,7 @@ void singletonWarnDestroyInstanceLeak(
} }
void singletonPrintDestructionStackTrace(const TypeDescriptor& type) { void singletonPrintDestructionStackTrace(const TypeDescriptor& type) {
auto trace = detail::getSingletonStackTrace(); auto trace = symbolizer::getStackTraceStr();
LOG(ERROR) << "Singleton " << type.name() << " was released.\n" LOG(ERROR) << "Singleton " << type.name() << " was released.\n"
<< "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)"); << "Stacktrace:\n" << (!trace.empty() ? trace : "(not available)");
} }
......
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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/detail/SingletonStackTrace.h>
#include <folly/experimental/symbolizer/ElfCache.h>
#include <folly/experimental/symbolizer/Symbolizer.h>
#include <folly/portability/Config.h>
namespace folly {
namespace detail {
std::string getSingletonStackTrace() {
#if FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
// Get and symbolize stack trace
constexpr size_t kMaxStackTraceDepth = 100;
auto addresses =
std::make_unique<symbolizer::FrameArray<kMaxStackTraceDepth>>();
if (!getStackTrace(*addresses)) {
return "";
} else {
symbolizer::ElfCache elfCache;
symbolizer::Symbolizer symbolizer(&elfCache);
symbolizer.symbolize(*addresses);
symbolizer::StringSymbolizePrinter printer;
printer.println(*addresses);
return printer.str();
}
#else
return "";
#endif // FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
}
} // namespace detail
} // namespace folly
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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.
*/
#pragma once
#include <string>
#include <folly/CPortability.h>
namespace folly {
namespace detail {
// empty-string indicates stack-trace functionality is not available
std::string getSingletonStackTrace();
} // namespace detail
} // namespace folly
...@@ -400,41 +400,15 @@ void SafeStackTracePrinter::printStackTrace(bool symbolize) { ...@@ -400,41 +400,15 @@ void SafeStackTracePrinter::printStackTrace(bool symbolize) {
} }
} }
std::string getStackTraceStr() {
#if FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
// Get and symbolize stack trace
constexpr size_t kMaxStackTraceDepth = 100;
FrameArray<kMaxStackTraceDepth> addresses;
if (!getStackTrace(addresses)) {
return "";
} else {
symbolizer::ElfCache elfCache;
symbolizer::Symbolizer symbolizer(&elfCache);
symbolizer.symbolize(addresses);
symbolizer::StringSymbolizePrinter printer;
printer.println(addresses);
return printer.str();
}
#else
return "";
#endif // FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
}
std::string getAsyncStackTraceStr() {
#if FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF #if FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
namespace {
constexpr size_t kMaxStackTraceDepth = 100;
// Get and symbolize stack trace template <size_t N, typename StackTraceFunc>
constexpr size_t kMaxStackTraceDepth = 100; std::string getStackTraceStrImpl(StackTraceFunc func) {
FrameArray<kMaxStackTraceDepth> addresses; FrameArray<N> addresses;
if (!getAsyncStackTraceSafe(addresses)) { if (!func(addresses)) {
return ""; return "";
} else { } else {
ElfCache elfCache; ElfCache elfCache;
...@@ -445,13 +419,19 @@ std::string getAsyncStackTraceStr() { ...@@ -445,13 +419,19 @@ std::string getAsyncStackTraceStr() {
printer.println(addresses); printer.println(addresses);
return printer.str(); return printer.str();
} }
}
} // namespace
#else std::string getStackTraceStr() {
return getStackTraceStrImpl<kMaxStackTraceDepth>(
return ""; getStackTrace<kMaxStackTraceDepth>);
}
#endif // FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF std::string getAsyncStackTraceStr() {
return getStackTraceStrImpl<kMaxStackTraceDepth>(
getAsyncStackTraceSafe<kMaxStackTraceDepth>);
} }
#endif // FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
#if FOLLY_HAVE_SWAPCONTEXT #if FOLLY_HAVE_SWAPCONTEXT
......
...@@ -243,6 +243,8 @@ class SafeStackTracePrinter { ...@@ -243,6 +243,8 @@ class SafeStackTracePrinter {
std::unique_ptr<FrameArray<kMaxStackTraceDepth>> addresses_; std::unique_ptr<FrameArray<kMaxStackTraceDepth>> addresses_;
}; };
#if FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
/** /**
* Gets the stack trace for the current thread and returns a string * Gets the stack trace for the current thread and returns a string
* representation. Convenience function meant for debugging and logging. * representation. Convenience function meant for debugging and logging.
...@@ -255,11 +257,25 @@ std::string getStackTraceStr(); ...@@ -255,11 +257,25 @@ std::string getStackTraceStr();
/** /**
* Gets the async stack trace for the current thread and returns a string * Gets the async stack trace for the current thread and returns a string
* representation. Convenience function meant for debugging and logging. * representation. Convenience function meant for debugging and logging.
* Empty string indicates stack trace functionality is not available.
* *
* NOT async-signal-safe. * NOT async-signal-safe.
*/ */
std::string getAsyncStackTraceStr(); std::string getAsyncStackTraceStr();
#else
// Define these in the header, as headers are always available, but not all
// platforms can link against the symbolizer library cpp sources.
inline std::string getStackTraceStr() {
return "";
}
inline std::string getAsyncStackTraceStr() {
return "";
}
#endif // FOLLY_HAVE_ELF && FOLLY_HAVE_DWARF
#if FOLLY_HAVE_SWAPCONTEXT #if FOLLY_HAVE_SWAPCONTEXT
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment