From c1e1c591e67a6be9ef1128de5c45229e91d94bd9 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Wed, 5 Feb 2020 22:43:22 -0500 Subject: SERVER-45677 libunwind on by default where possible - tcmalloc to not use libunwind API, as it uses slow cursor steps. - Remove UNW_LOCAL_ONLY from CXXFLAGS everywhere. --- src/mongo/SConscript | 3 ++- src/mongo/config.h.in | 3 +++ src/mongo/util/signal_handlers.cpp | 21 +++++++++++++++++---- src/mongo/util/signal_handlers_synchronous.cpp | 4 +--- src/mongo/util/signal_handlers_synchronous.h | 6 +++++- src/mongo/util/stacktrace.h | 3 ++- src/mongo/util/stacktrace_bm.cpp | 7 ++++--- src/mongo/util/stacktrace_libunwind_test.cpp | 1 + src/mongo/util/stacktrace_posix.cpp | 3 ++- src/mongo/util/stacktrace_test.cpp | 2 +- src/mongo/util/tcmalloc_parameters.idl | 4 ++-- 11 files changed, 40 insertions(+), 17 deletions(-) (limited to 'src/mongo') diff --git a/src/mongo/SConscript b/src/mongo/SConscript index f12d196834b..ed2c87c6be7 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -56,7 +56,7 @@ env.SConscript( # it, and do not declare other libraries in this file. baseEnv = env.Clone() -if use_libunwind: +if use_libunwind == True: baseEnv.InjectThirdParty('unwind') stacktrace_impl_cpp = [ File('util/stacktrace_${TARGET_OS_FAMILY}.cpp') ] @@ -309,6 +309,7 @@ config_header_substs = ( ('@mongo_config_ssl_provider@', 'MONGO_CONFIG_SSL_PROVIDER'), ('@mongo_config_usdt_enabled@', 'MONGO_CONFIG_USDT_ENABLED'), ('@mongo_config_usdt_provider@', 'MONGO_CONFIG_USDT_PROVIDER'), + ('@mongo_config_use_libunwind@', 'MONGO_CONFIG_USE_LIBUNWIND'), ('@mongo_config_wiredtiger_enabled@', 'MONGO_CONFIG_WIREDTIGER_ENABLED'), ) diff --git a/src/mongo/config.h.in b/src/mongo/config.h.in index c7a9e1f5fd9..54e7a14787d 100644 --- a/src/mongo/config.h.in +++ b/src/mongo/config.h.in @@ -89,5 +89,8 @@ // Set to which provider defines USDT @mongo_config_usdt_provider@ +// Defined if using libunwind. +@mongo_config_use_libunwind@ + // Defined if WiredTiger storage engine is enabled @mongo_config_wiredtiger_enabled@ diff --git a/src/mongo/util/signal_handlers.cpp b/src/mongo/util/signal_handlers.cpp index 8c8d04c6254..9224b6ee466 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -205,7 +205,7 @@ void handleOneSignal(const SignalWaitResult& waited, LogRotationState* rotation) "got signal {sig} ({strsignal_sig})", "sig"_attr = sig, "strsignal_sig"_attr = strsignal(sig)); -#ifdef __linux__ +#if defined(__linux__) const siginfo_t& si = waited.si; switch (si.si_code) { case SI_USER: @@ -239,12 +239,18 @@ void handleOneSignal(const SignalWaitResult& waited, LogRotationState* rotation) } return; } -#if defined(MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS) + +#if defined(MONGO_STACKTRACE_HAS_SIGNAL) if (sig == stackTraceSignal()) { + // If there's a stackTraceSignal at all, catch it here so we don't die from it. + // Can dump all threads if we can, else silently ignore it. +#if defined(MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS) printAllThreadStacks(); +#endif return; } #endif + // interrupt/terminate signal LOGV2(23381, "will terminate after current cmd ends"); exitCleanly(EXIT_CLEAN); @@ -265,8 +271,8 @@ void signalProcessingThread(LogFileStatus rotate) { for (int sig : kSignalProcessingThreadExclusives) sigaddset(&waitSignals, sig); -#if defined(MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS) - // On this thread, block the stackTraceSignal and rely on sigwaitinfo to deliver it. +#if defined(MONGO_STACKTRACE_HAS_SIGNAL) + // On this thread, block the stackTraceSignal and rely on a signal wait to deliver it. sigaddset(&waitSignals, stackTraceSignal()); #endif @@ -317,6 +323,13 @@ void startSignalProcessingThread(LogFileStatus rotate) { for (int sig : kSignalProcessingThreadExclusives) sigaddset(&sigset, sig); +#if defined(MONGO_STACKTRACE_HAS_SIGNAL) && !defined(MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS) + // On a Unixlike build without the stacktrace behavior, we still want to handle SIGUSR2 to + // print a message, but it must only go to the signalProcessingThread, not on other threads. + // It's as if stackTraceSignal (e.g. SIGUSR2) is a member of kSignalProcessingThreadExclusives. + sigaddset(&sigset, stackTraceSignal()); +#endif + // Mask signals in the current (only) thread. All new threads will inherit this mask. invariant(pthread_sigmask(SIG_SETMASK, &sigset, nullptr) == 0); // Spawn a thread to capture the signals we just masked off. diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index 86b48d46a09..be2a2bd175f 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -361,12 +361,10 @@ void clearSignalMask() { #endif } -#ifdef __linux__ - +#if defined(MONGO_STACKTRACE_HAS_SIGNAL) int stackTraceSignal() { return SIGUSR2; } - #endif } // namespace mongo diff --git a/src/mongo/util/signal_handlers_synchronous.h b/src/mongo/util/signal_handlers_synchronous.h index 53a5ff1fe2d..ceb513c4600 100644 --- a/src/mongo/util/signal_handlers_synchronous.h +++ b/src/mongo/util/signal_handlers_synchronous.h @@ -57,7 +57,11 @@ void reportOutOfMemoryErrorAndExit(); */ void clearSignalMask(); -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) +#define MONGO_STACKTRACE_HAS_SIGNAL +#endif + +#if defined(MONGO_STACKTRACE_HAS_SIGNAL) /** * Returns the signal used to initiate all-thread stack traces. */ diff --git a/src/mongo/util/stacktrace.h b/src/mongo/util/stacktrace.h index 01a300a06a6..535199862c3 100644 --- a/src/mongo/util/stacktrace.h +++ b/src/mongo/util/stacktrace.h @@ -36,6 +36,7 @@ #include #include "mongo/base/string_data.h" +#include "mongo/config.h" /** * All-thread backtrace is only implemented on Linux. Even on Linux, it's only AS-safe @@ -45,7 +46,7 @@ * - markAsStackTraceProcessingThread * - printAllThreadStacks */ -#if defined(__linux__) && defined(MONGO_USE_LIBUNWIND) +#if defined(__linux__) && defined(MONGO_CONFIG_USE_LIBUNWIND) #define MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS #endif diff --git a/src/mongo/util/stacktrace_bm.cpp b/src/mongo/util/stacktrace_bm.cpp index 8638e9de058..b2df446d07b 100644 --- a/src/mongo/util/stacktrace_bm.cpp +++ b/src/mongo/util/stacktrace_bm.cpp @@ -47,7 +47,8 @@ #include "mongo/util/decimal_counter.h" #include "mongo/util/stacktrace.h" -#if defined(MONGO_USE_LIBUNWIND) +#if defined(MONGO_CONFIG_USE_LIBUNWIND) +#define UNW_LOCAL_ONLY #include #endif @@ -101,7 +102,7 @@ void BM_Print(benchmark::State& state) { } BENCHMARK(BM_Print)->Range(1, 100); -#if defined(MONGO_USE_LIBUNWIND) +#if defined(MONGO_CONFIG_USE_LIBUNWIND) void BM_CursorSteps(benchmark::State& state) { size_t items = 0; RecursionParam param; @@ -134,7 +135,7 @@ void BM_CursorSteps(benchmark::State& state) { state.SetItemsProcessed(items); } BENCHMARK(BM_CursorSteps)->Range(1, 100); -#endif // MONGO_USE_LIBUNWIND +#endif // MONGO_CONFIG_USE_LIBUNWIND } // namespace diff --git a/src/mongo/util/stacktrace_libunwind_test.cpp b/src/mongo/util/stacktrace_libunwind_test.cpp index 3628452cf88..f89a08c0c3f 100644 --- a/src/mongo/util/stacktrace_libunwind_test.cpp +++ b/src/mongo/util/stacktrace_libunwind_test.cpp @@ -38,6 +38,7 @@ #include #include +#define UNW_LOCAL_ONLY #include #include "mongo/unittest/unittest.h" diff --git a/src/mongo/util/stacktrace_posix.cpp b/src/mongo/util/stacktrace_posix.cpp index ced0438ab10..18f6bae2dd4 100644 --- a/src/mongo/util/stacktrace_posix.cpp +++ b/src/mongo/util/stacktrace_posix.cpp @@ -55,7 +55,7 @@ #define MONGO_STACKTRACE_BACKEND_LIBUNWIND 1 #define MONGO_STACKTRACE_BACKEND_EXECINFO 2 -#if defined(MONGO_USE_LIBUNWIND) +#if defined(MONGO_CONFIG_USE_LIBUNWIND) #define MONGO_STACKTRACE_BACKEND MONGO_STACKTRACE_BACKEND_LIBUNWIND #elif defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) #define MONGO_STACKTRACE_BACKEND MONGO_STACKTRACE_BACKEND_EXECINFO @@ -64,6 +64,7 @@ #endif #if MONGO_STACKTRACE_BACKEND == MONGO_STACKTRACE_BACKEND_LIBUNWIND +#define UNW_LOCAL_ONLY #include #elif MONGO_STACKTRACE_BACKEND == MONGO_STACKTRACE_BACKEND_EXECINFO #include diff --git a/src/mongo/util/stacktrace_test.cpp b/src/mongo/util/stacktrace_test.cpp index 66d53a926d7..e8a57699caa 100644 --- a/src/mongo/util/stacktrace_test.cpp +++ b/src/mongo/util/stacktrace_test.cpp @@ -858,7 +858,7 @@ TEST_F(PrintAllThreadStacksTest, Go_200_Threads) { #endif // defined(MONGO_STACKTRACE_CAN_DUMP_ALL_THREADS) -#if defined(MONGO_USE_LIBUNWIND) || defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) +#if defined(MONGO_CONFIG_USE_LIBUNWIND) || defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) /** * Try to backtrace from a stack containing a libc function. To do this * we need a libc function that makes a user-provided callback, like qsort. diff --git a/src/mongo/util/tcmalloc_parameters.idl b/src/mongo/util/tcmalloc_parameters.idl index 15993865720..70586cda5e3 100644 --- a/src/mongo/util/tcmalloc_parameters.idl +++ b/src/mongo/util/tcmalloc_parameters.idl @@ -54,7 +54,7 @@ server_parameters: cpp_varname: HeapProfilingEnabled default: false condition: - preprocessor: defined(_POSIX_VERSION) && (defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) || defined(MONGO_USE_LIBUNWIND)) + preprocessor: defined(_POSIX_VERSION) && (defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) || defined(MONGO_CONFIG_USE_LIBUNWIND)) heapProfilingSampleIntervalBytes: description: "Configure heap profiling sample interval bytes" @@ -64,7 +64,7 @@ server_parameters: # 256kb default: 262144 condition: - preprocessor: defined(_POSIX_VERSION) && (defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) || defined(MONGO_USE_LIBUNWIND)) + preprocessor: defined(_POSIX_VERSION) && (defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) || defined(MONGO_CONFIG_USE_LIBUNWIND)) tcmallocEnableMarkThreadTemporarilyIdle: description: 'REMOVED: Setting this parameter has no effect and it will be removed in a future version of MongoDB.' -- cgit v1.2.1