diff options
-rw-r--r-- | src/mongo/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/util/stacktrace.cpp (renamed from src/mongo/util/stacktrace_json.cpp) | 26 | ||||
-rw-r--r-- | src/mongo/util/stacktrace.h | 56 | ||||
-rw-r--r-- | src/mongo/util/stacktrace_json.h | 90 | ||||
-rw-r--r-- | src/mongo/util/stacktrace_posix.cpp | 30 | ||||
-rw-r--r-- | src/mongo/util/stacktrace_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/util/stacktrace_threads.cpp | 1 | ||||
-rw-r--r-- | src/mongo/util/stacktrace_windows.cpp | 33 |
8 files changed, 89 insertions, 150 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index c1f03448b1a..3242cd1fbb5 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -157,8 +157,8 @@ baseEnv.Library( 'util/platform_init.cpp', 'util/shell_exec.cpp', 'util/signal_handlers_synchronous.cpp', + 'util/stacktrace.cpp', 'util/stacktrace_${TARGET_OS_FAMILY}.cpp', - 'util/stacktrace_json.cpp', 'util/stacktrace_somap.cpp', 'util/stacktrace_threads.cpp', 'util/str.cpp', diff --git a/src/mongo/util/stacktrace_json.cpp b/src/mongo/util/stacktrace.cpp index 12f2b06268e..2725d40d200 100644 --- a/src/mongo/util/stacktrace_json.cpp +++ b/src/mongo/util/stacktrace.cpp @@ -27,11 +27,15 @@ * it in the license file. */ -#include "mongo/util/stacktrace_json.h" +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kControl + +#include "mongo/util/stacktrace.h" #include <cctype> #include "mongo/bson/bsonobj.h" +#include "mongo/bson/json.h" +#include "mongo/logv2/log.h" #include "mongo/util/assert_util.h" namespace mongo::stack_trace_detail { @@ -89,4 +93,24 @@ uint64_t Hex::fromHex(StringData s) { return x; } +void logBacktraceObject(const BSONObj& bt, StackTraceSink* sink, bool withHumanReadable) { + if (sink) { + *sink << fmt::format(FMT_STRING("BACKTRACE: {}"), tojson(bt, ExtendedRelaxedV2_0_0)); + } else { + LOGV2_OPTIONS(31380, {logv2::LogTruncation::Disabled}, "BACKTRACE", "bt"_attr = bt); + } + if (withHumanReadable) { + if (auto elem = bt.getField("backtrace"); !elem.eoo()) { + for (const auto& fe : elem.Obj()) { + BSONObj frame = fe.Obj(); + if (sink) { + *sink << fmt::format("\n Frame: {}", tojson(frame, ExtendedRelaxedV2_0_0)); + } else { + LOGV2(31445, "Frame", "frame"_attr = frame); + } + } + } + } +} + } // namespace mongo::stack_trace_detail diff --git a/src/mongo/util/stacktrace.h b/src/mongo/util/stacktrace.h index 535199862c3..e36a0aea03b 100644 --- a/src/mongo/util/stacktrace.h +++ b/src/mongo/util/stacktrace.h @@ -32,10 +32,12 @@ */ #pragma once +#include <array> #include <iosfwd> #include <string> #include "mongo/base/string_data.h" +#include "mongo/bson/bsonobj.h" #include "mongo/config.h" /** @@ -89,6 +91,60 @@ private: std::string& _s; }; +namespace stack_trace_detail { +/** + * A utility for uint64_t <=> uppercase hex string conversions. It + * can be used to produce a StringData. + * + * sink << Hex(x); // as a temporary + * + * Hex hx(x); + * StringData sd = hx; // sd storage is in `hx`. + */ +class Hex { +public: + using Buf = std::array<char, 18>; // 64/4 hex digits plus potential "0x" + + static StringData toHex(uint64_t x, Buf& buf, bool showBase = false); + + static uint64_t fromHex(StringData s); + + explicit Hex(uint64_t x, bool showBase = false) : _str{toHex(x, _buf, showBase)} {} + explicit Hex(const void* x, bool showBase = false) + : Hex{reinterpret_cast<uintptr_t>(x), showBase} {} + + operator StringData() const { + return _str; + } + +private: + Buf _buf; + StringData _str; +}; + +class Dec { +public: + using Buf = std::array<char, 20>; // ceil(64*log10(2)) + + static StringData toDec(uint64_t x, Buf& buf); + + static uint64_t fromDec(StringData s); + + explicit Dec(uint64_t x) : _str(toDec(x, _buf)) {} + + operator StringData() const { + return _str; + } + +private: + Buf _buf; + StringData _str; +}; + +void logBacktraceObject(const BSONObj& bt, StackTraceSink* sink, bool withHumanReadable); + +} // namespace stack_trace_detail + #ifndef _WIN32 /** * Metadata about an instruction address. diff --git a/src/mongo/util/stacktrace_json.h b/src/mongo/util/stacktrace_json.h deleted file mode 100644 index 554b1a66537..00000000000 --- a/src/mongo/util/stacktrace_json.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <array> -#include <ostream> - -#include "mongo/base/string_data.h" -#include "mongo/bson/bsonelement.h" -#include "mongo/util/stacktrace.h" - -namespace mongo::stack_trace_detail { - -/** - * A utility for uint64_t <=> uppercase hex string conversions. It - * can be used to produce a StringData. - * - * sink << Hex(x); // as a temporary - * - * Hex hx(x); - * StringData sd = hx; // sd storage is in `hx`. - */ -class Hex { -public: - using Buf = std::array<char, 18>; // 64/4 hex digits plus potential "0x" - - static StringData toHex(uint64_t x, Buf& buf, bool showBase = false); - - static uint64_t fromHex(StringData s); - - explicit Hex(uint64_t x, bool showBase = false) : _str{toHex(x, _buf, showBase)} {} - explicit Hex(const void* x, bool showBase = false) - : Hex{reinterpret_cast<uintptr_t>(x), showBase} {} - - operator StringData() const { - return _str; - } - -private: - Buf _buf; - StringData _str; -}; - -class Dec { -public: - using Buf = std::array<char, 20>; // ceil(64*log10(2)) - - static StringData toDec(uint64_t x, Buf& buf); - - static uint64_t fromDec(StringData s); - - explicit Dec(uint64_t x) : _str(toDec(x, _buf)) {} - - operator StringData() const { - return _str; - } - -private: - Buf _buf; - StringData _str; -}; - -} // namespace mongo::stack_trace_detail diff --git a/src/mongo/util/stacktrace_posix.cpp b/src/mongo/util/stacktrace_posix.cpp index 531e21bdc24..9d27ca1af25 100644 --- a/src/mongo/util/stacktrace_posix.cpp +++ b/src/mongo/util/stacktrace_posix.cpp @@ -48,7 +48,6 @@ #include "mongo/logv2/log.h" #include "mongo/platform/compiler_gcc.h" #include "mongo/util/scopeguard.h" -#include "mongo/util/stacktrace_json.h" #include "mongo/util/stacktrace_somap.h" #include "mongo/util/version.h" @@ -426,38 +425,15 @@ void printStackTraceImpl(const Options& options, StackTraceSink* sink = nullptr) appendStackTraceObject(&bob, iteration, options); #endif - BSONObj obj = bob.done(); if (!err.empty()) { - static constexpr char fmtErr[] = "Error collecting stack trace: {err}"; if (sink) { - *sink << fmt::format(fmtErr, "err"_a = err); + *sink << fmt::format(FMT_STRING("Error collecting stack trace: {}"), err); } else { - LOGV2(31430, fmtErr, "err"_attr = err); + LOGV2(31430, "Error collecting stack trace", "error"_attr = err); } return; } - static constexpr char fmtBt[] = "BACKTRACE: {bt}"; - if (sink) { - *sink << fmt::format(fmtBt, "bt"_a = tojson(obj, ExtendedRelaxedV2_0_0)); - } else { - LOGV2_OPTIONS(31431, {logv2::LogTruncation::Disabled}, fmtBt, "bt"_attr = obj); - } - - if (options.withHumanReadable) { - if (auto elem = obj.getField("backtrace"); !elem.eoo()) { - for (const auto& fe : elem.embeddedObject()) { - BSONObj frame = fe.embeddedObject(); - static constexpr char fmtFrame[] = " Frame: {frame}"; - if (sink) { - *sink << "\n" - << fmt::format(fmtFrame, - "frame"_a = tojson(frame, ExtendedRelaxedV2_0_0)); - } else { - LOGV2(31427, fmtFrame, "frame"_attr = frame); - } - } - } - } + stack_trace_detail::logBacktraceObject(bob.done(), sink, options.withHumanReadable); } diff --git a/src/mongo/util/stacktrace_test.cpp b/src/mongo/util/stacktrace_test.cpp index 4de985fde00..e5978736041 100644 --- a/src/mongo/util/stacktrace_test.cpp +++ b/src/mongo/util/stacktrace_test.cpp @@ -55,7 +55,6 @@ #include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" #include "mongo/util/stacktrace.h" -#include "mongo/util/stacktrace_json.h" /** `sigaltstack` was introduced in glibc-2.12 in 2010. */ #if !defined(_WIN32) diff --git a/src/mongo/util/stacktrace_threads.cpp b/src/mongo/util/stacktrace_threads.cpp index d2d8e38539e..62fe41898a2 100644 --- a/src/mongo/util/stacktrace_threads.cpp +++ b/src/mongo/util/stacktrace_threads.cpp @@ -60,7 +60,6 @@ #include "mongo/stdx/thread.h" #include "mongo/stdx/unordered_map.h" #include "mongo/util/signal_handlers_synchronous.h" -#include "mongo/util/stacktrace_json.h" #include "mongo/util/stacktrace_somap.h" namespace mongo { diff --git a/src/mongo/util/stacktrace_windows.cpp b/src/mongo/util/stacktrace_windows.cpp index 14f00b58f25..c95911d112c 100644 --- a/src/mongo/util/stacktrace_windows.cpp +++ b/src/mongo/util/stacktrace_windows.cpp @@ -59,7 +59,6 @@ #include "mongo/stdx/mutex.h" #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/mutex.h" -#include "mongo/util/stacktrace_json.h" #include "mongo/util/text.h" namespace mongo { @@ -96,9 +95,8 @@ public: const auto symbolPath = symbolPathBuilder.str(); if (!SymInitializeW(handle, symbolPath.c_str(), TRUE)) { - LOGV2_ERROR(31443, - "Stack trace initialization failed, SymInitialize failed with error {err}", - "err"_attr = errnoWithDescription()); + LOGV2_ERROR( + 31443, "Stack trace initialization failed", "error"_attr = errnoWithDescription()); return; } @@ -244,7 +242,7 @@ std::vector<TraceItem> makeTraceList(CONTEXT& context) { stdx::lock_guard<SymbolHandler> lk(symbolHandler); if (!symbolHandler) { - LOGV2_ERROR(31444, "Stack trace failed, symbol handler returned an invalid handle."); + LOGV2_ERROR(31444, "Stack trace failed, symbol handler returned an invalid handle"); return traceList; } @@ -307,30 +305,7 @@ void printTraceList(const std::vector<TraceItem>& traceList, return; BSONObjBuilder bob; appendTrace(&bob, traceList, options); - const BSONObj bt = bob.done(); - - static constexpr char fmtBt[] = "BACKTRACE: {bt}"; - if (sink) { - *sink << fmt::format(fmtBt, "bt"_a = tojson(bt, ExtendedRelaxedV2_0_0)); - } else { - LOGV2_OPTIONS(31380, {logv2::LogTruncation::Disabled}, fmtBt, "bt"_attr = bt); - } - - if (options.withHumanReadable) { - if (auto elem = bt.getField("backtrace"); !elem.eoo()) { - for (const auto& fe : elem.Obj()) { - BSONObj frame = fe.Obj(); - static constexpr char fmtFrame[] = " Frame: {frame}"; - if (sink) { - *sink << "\n" - << fmt::format(fmtFrame, - "frame"_a = tojson(frame, ExtendedRelaxedV2_0_0)); - } else { - LOGV2(31445, fmtFrame, "frame"_attr = frame); - } - } - } - } + stack_trace_detail::logBacktraceObject(bob.done(), sink, options.withHumanReadable); } /** `sink` can be nullptr to emit structured logs instead of writing to a sink. */ |