Commit 792d3247 authored by Matt Ma's avatar Matt Ma Committed by Facebook GitHub Bot

Resubmit: Allow using different symbolizer mode in signal handler.

Summary: Fixed the missed initialization in InitOptions.

Reviewed By: luciang

Differential Revision: D22023637

fbshipit-source-id: 25d4049019e42708c98e5b589ed4838e2870d39b
parent 8d4e8ede
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <folly/experimental/exception_tracer/ExceptionAbi.h> #include <folly/experimental/exception_tracer/ExceptionAbi.h>
#include <folly/experimental/exception_tracer/StackTrace.h> #include <folly/experimental/exception_tracer/StackTrace.h>
#include <folly/experimental/symbolizer/Symbolizer.h> #include <folly/experimental/symbolizer/Symbolizer.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
namespace { namespace {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/experimental/symbolizer/Elf.h> #include <folly/experimental/symbolizer/Elf.h>
#include <folly/experimental/symbolizer/SymbolizedFrame.h> #include <folly/experimental/symbolizer/SymbolizedFrame.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
namespace folly { namespace folly {
namespace symbolizer { namespace symbolizer {
......
...@@ -493,7 +493,9 @@ bool isSmallSigAltStackEnabled() { ...@@ -493,7 +493,9 @@ bool isSmallSigAltStackEnabled() {
} // namespace } // namespace
void installFatalSignalHandler(std::bitset<64> signals) { void installFatalSignalHandler(
std::bitset<64> signals,
LocationInfoMode symbolizerMode) {
if (gAlreadyInstalled.exchange(true)) { if (gAlreadyInstalled.exchange(true)) {
// Already done. // Already done.
return; return;
...@@ -509,9 +511,11 @@ void installFatalSignalHandler(std::bitset<64> signals) { ...@@ -509,9 +511,11 @@ void installFatalSignalHandler(std::bitset<64> signals) {
// stack overflow. Replace it with the unsafe self-allocate printer. // stack overflow. Replace it with the unsafe self-allocate printer.
bool useUnsafePrinter = isSmallSigAltStackEnabled(); bool useUnsafePrinter = isSmallSigAltStackEnabled();
if (useUnsafePrinter) { if (useUnsafePrinter) {
gStackTracePrinter = new UnsafeSelfAllocateStackTracePrinter(); gStackTracePrinter =
new UnsafeSelfAllocateStackTracePrinter(STDERR_FILENO, symbolizerMode);
} else { } else {
gStackTracePrinter = new SafeStackTracePrinter(); gStackTracePrinter =
new SafeStackTracePrinter(STDERR_FILENO, symbolizerMode);
} }
struct sigaction sa; struct sigaction sa;
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include <bitset> #include <bitset>
#include <functional> #include <functional>
#include <folly/experimental/symbolizer/SymbolizedFrame.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
namespace folly { namespace folly {
namespace symbolizer { namespace symbolizer {
...@@ -36,7 +39,8 @@ extern const unsigned long kAllFatalSignals; ...@@ -36,7 +39,8 @@ extern const unsigned long kAllFatalSignals;
* are honored in this list, other signals are ignored. * are honored in this list, other signals are ignored.
*/ */
void installFatalSignalHandler( void installFatalSignalHandler(
std::bitset<64> signals = std::bitset<64>(kAllFatalSignals)); std::bitset<64> signals = std::bitset<64>(kAllFatalSignals),
LocationInfoMode symbolizerMode = LocationInfoMode::FULL);
/** /**
* Add a callback to be run when receiving a fatal signal. They will also * Add a callback to be run when receiving a fatal signal. They will also
......
...@@ -80,18 +80,6 @@ inline std::ostream& operator<<(std::ostream& out, const Path& path) { ...@@ -80,18 +80,6 @@ inline std::ostream& operator<<(std::ostream& out, const Path& path) {
return out << path.toString(); return out << path.toString();
} }
enum class LocationInfoMode {
// Don't resolve location info.
DISABLED,
// Perform CU lookup using .debug_aranges (might be incomplete).
FAST,
// Scan all CU in .debug_info (slow!) on .debug_aranges lookup failure.
FULL,
// Scan .debug_info (super slower, use with caution) for inline functions in
// addition to FULL.
FULL_WITH_INLINE,
};
/** /**
* Contains location info like file name, line number, etc. * Contains location info like file name, line number, etc.
*/ */
......
...@@ -472,8 +472,9 @@ void StringSymbolizePrinter::doPrint(StringPiece sp) { ...@@ -472,8 +472,9 @@ void StringSymbolizePrinter::doPrint(StringPiece sp) {
buf_.append(sp.data(), sp.size()); buf_.append(sp.data(), sp.size());
} }
SafeStackTracePrinter::SafeStackTracePrinter(int fd) SafeStackTracePrinter::SafeStackTracePrinter(int fd, LocationInfoMode mode)
: fd_(fd), : fd_(fd),
mode_(mode),
printer_( printer_(
fd, fd,
SymbolizePrinter::COLOR_IF_TTY, SymbolizePrinter::COLOR_IF_TTY,
...@@ -493,15 +494,19 @@ void SafeStackTracePrinter::printSymbolizedStackTrace() { ...@@ -493,15 +494,19 @@ void SafeStackTracePrinter::printSymbolizedStackTrace() {
// Do our best to populate location info, process is going to terminate, // Do our best to populate location info, process is going to terminate,
// so performance isn't critical. // so performance isn't critical.
SignalSafeElfCache elfCache_; SignalSafeElfCache elfCache_;
Symbolizer symbolizer(&elfCache_, LocationInfoMode::FULL); Symbolizer symbolizer(&elfCache_, mode_);
symbolizer.symbolize(*addresses_); symbolizer.symbolize(*addresses_);
// Skip the top 2 frames captured by printStackTrace: // Skip the top 2 frames (4 frames if inline functions are included) captured
// getStackTraceSafe // by printStackTrace:
// * getStackTraceInPlace (marked as inline in StackTrace.cpp)
// getStackTraceSafe (in StackTrace.cpp)
// * getStackTraceSafe<N> (marked as inline in Symbolizer.h)
// SafeStackTracePrinter::printStackTrace (captured stack) // SafeStackTracePrinter::printStackTrace (captured stack)
// //
// Leaving signalHandler on the stack for clarity, I think. // Leaving signalHandler on the stack for clarity, I think.
printer_.println(*addresses_, 2); printer_.println(
*addresses_, mode_ == LocationInfoMode::FULL_WITH_INLINE ? 4 : 2);
} }
void SafeStackTracePrinter::printStackTrace(bool symbolize) { void SafeStackTracePrinter::printStackTrace(bool symbolize) {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <folly/experimental/symbolizer/ElfCache.h> #include <folly/experimental/symbolizer/ElfCache.h>
#include <folly/experimental/symbolizer/StackTrace.h> #include <folly/experimental/symbolizer/StackTrace.h>
#include <folly/experimental/symbolizer/SymbolizedFrame.h> #include <folly/experimental/symbolizer/SymbolizedFrame.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
#include <folly/io/IOBuf.h> #include <folly/io/IOBuf.h>
namespace folly { namespace folly {
...@@ -125,9 +126,10 @@ class Symbolizer { ...@@ -125,9 +126,10 @@ class Symbolizer {
template <size_t N> template <size_t N>
size_t symbolize(FrameArray<N>& fa) { size_t symbolize(FrameArray<N>& fa) {
return symbolize( fa.frameCount = symbolize(
folly::Range<const uintptr_t*>(fa.addresses, fa.frameCount), folly::Range<const uintptr_t*>(fa.addresses, fa.frameCount),
folly::Range<SymbolizedFrame*>(fa.frames, N)); folly::Range<SymbolizedFrame*>(fa.frames, N));
return fa.frameCount;
} }
/** /**
...@@ -347,7 +349,9 @@ class StringSymbolizePrinter : public SymbolizePrinter { ...@@ -347,7 +349,9 @@ class StringSymbolizePrinter : public SymbolizePrinter {
*/ */
class SafeStackTracePrinter { class SafeStackTracePrinter {
public: public:
explicit SafeStackTracePrinter(int fd = STDERR_FILENO); explicit SafeStackTracePrinter(
int fd = STDERR_FILENO,
LocationInfoMode mode = LocationInfoMode::FULL);
virtual ~SafeStackTracePrinter() {} virtual ~SafeStackTracePrinter() {}
...@@ -374,7 +378,8 @@ class SafeStackTracePrinter { ...@@ -374,7 +378,8 @@ class SafeStackTracePrinter {
private: private:
static constexpr size_t kMaxStackTraceDepth = 100; static constexpr size_t kMaxStackTraceDepth = 100;
int fd_; const int fd_;
const LocationInfoMode mode_;
FDSymbolizePrinter printer_; FDSymbolizePrinter printer_;
std::unique_ptr<FrameArray<kMaxStackTraceDepth>> addresses_; std::unique_ptr<FrameArray<kMaxStackTraceDepth>> addresses_;
}; };
...@@ -422,6 +427,12 @@ class FastStackTracePrinter { ...@@ -422,6 +427,12 @@ class FastStackTracePrinter {
* Note it's still unsafe even with that. * Note it's still unsafe even with that.
*/ */
class UnsafeSelfAllocateStackTracePrinter : public SafeStackTracePrinter { class UnsafeSelfAllocateStackTracePrinter : public SafeStackTracePrinter {
public:
explicit UnsafeSelfAllocateStackTracePrinter(
int fd = STDERR_FILENO,
LocationInfoMode mode = LocationInfoMode::FULL)
: SafeStackTracePrinter(fd, mode) {}
protected: protected:
void printSymbolizedStackTrace() override; void printSymbolizedStackTrace() override;
const long pageSizeUnchecked_ = sysconf(_SC_PAGESIZE); const long pageSizeUnchecked_ = sysconf(_SC_PAGESIZE);
......
/*
* Copyright (c) Facebook, Inc. and its 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
namespace folly {
namespace symbolizer {
enum class LocationInfoMode {
// Don't resolve location info.
DISABLED,
// Perform CU lookup using .debug_aranges (might be incomplete).
FAST,
// Scan all CU in .debug_info (slow!) on .debug_aranges lookup failure.
FULL,
// Scan .debug_info (super slower, use with caution) for inline functions in
// addition to FULL.
FULL_WITH_INLINE,
};
} // namespace symbolizer
} // namespace folly
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/experimental/symbolizer/Dwarf.h> #include <folly/experimental/symbolizer/Dwarf.h>
#include <folly/experimental/symbolizer/SymbolizedFrame.h> #include <folly/experimental/symbolizer/SymbolizedFrame.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
#include <folly/experimental/symbolizer/test/SymbolizerTestUtils.h> #include <folly/experimental/symbolizer/test/SymbolizerTestUtils.h>
#include <folly/portability/GFlags.h> #include <folly/portability/GFlags.h>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <folly/experimental/TestUtil.h> #include <folly/experimental/TestUtil.h>
#include <folly/experimental/symbolizer/StackTrace.h> #include <folly/experimental/symbolizer/StackTrace.h>
#include <folly/experimental/symbolizer/Symbolizer.h> #include <folly/experimental/symbolizer/Symbolizer.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
#include <folly/test/TestUtils.h> #include <folly/test/TestUtils.h>
#include <boost/regex.hpp> #include <boost/regex.hpp>
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/String.h> #include <folly/String.h>
#include <folly/experimental/symbolizer/SymbolizedFrame.h> #include <folly/experimental/symbolizer/SymbolizedFrame.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
#include <folly/experimental/symbolizer/test/SymbolizerTestUtils.h> #include <folly/experimental/symbolizer/test/SymbolizerTestUtils.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
#include <folly/test/TestUtils.h> #include <folly/test/TestUtils.h>
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
#include <folly/synchronization/HazptrThreadPoolExecutor.h> #include <folly/synchronization/HazptrThreadPoolExecutor.h>
#if FOLLY_USE_SYMBOLIZER #if FOLLY_USE_SYMBOLIZER
// @manual because autodeps doesn't understand `os_deps` and suggests
// adding dep to `deps`.
#include <folly/experimental/symbolizer/SignalHandler.h> // @manual #include <folly/experimental/symbolizer/SignalHandler.h> // @manual
#include <folly/experimental/symbolizer/SymbolizedFrame.h> // @manual
#endif #endif
#include <folly/portability/GFlags.h> #include <folly/portability/GFlags.h>
...@@ -51,7 +54,8 @@ void init(int* argc, char*** argv, InitOptions options) { ...@@ -51,7 +54,8 @@ void init(int* argc, char*** argv, InitOptions options) {
#if FOLLY_USE_SYMBOLIZER #if FOLLY_USE_SYMBOLIZER
// Install the handler now, to trap errors received during startup. // Install the handler now, to trap errors received during startup.
// The callbacks, if any, can be installed later // The callbacks, if any, can be installed later
folly::symbolizer::installFatalSignalHandler(options.fatal_signals); folly::symbolizer::installFatalSignalHandler(
options.fatal_signals, options.fatalSignalsSymbolizerMode);
#elif !defined(_WIN32) #elif !defined(_WIN32)
google::InstallFailureSignalHandler(); google::InstallFailureSignalHandler();
#endif #endif
......
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
*/ */
#pragma once #pragma once
#include <folly/CPortability.h>
#include <bitset> #include <bitset>
#include <folly/CPortability.h>
#include <folly/experimental/symbolizer/SymbolizerMode.h>
namespace folly { namespace folly {
class InitOptions { class InitOptions {
public: public:
...@@ -25,13 +28,17 @@ class InitOptions { ...@@ -25,13 +28,17 @@ class InitOptions {
bool remove_flags{true}; bool remove_flags{true};
// mask of all fatal (default handler of terminating the process) signals for // Mask of all fatal (default handler of terminating the process) signals for
// which `init()` will install handler that print stack traces and invokes // which `init()` will install handler that print stack traces and invokes
// previously established handler (or terminate if there were none). // previously established handler (or terminate if there were none).
// Signals that are not in `symbolizer::kAllFatalSignals` will be ignored // Signals that are not in `symbolizer::kAllFatalSignals` will be ignored
// if passed here // if passed here.
// Defaults to all signal in `symbolizer::kAllFatalSignals` // Defaults to all signal in `symbolizer::kAllFatalSignals`.
// Both fatal_signals and symbolizerMode are only used when folly symbolizer
// is enabled.
std::bitset<64> fatal_signals; std::bitset<64> fatal_signals;
folly::symbolizer::LocationInfoMode fatalSignalsSymbolizerMode =
folly::symbolizer::LocationInfoMode::FULL;
InitOptions& removeFlags(bool remove) { InitOptions& removeFlags(bool remove) {
remove_flags = remove; remove_flags = remove;
......
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