Co-authored-by: Alex Li <alex.li@mongodb.com> Co-authored-by: Ryan Berryhill <ryan.berryhill@mongodb.com> Co-authored-by: Guillaume Racicot <guillaume.racicot@mongodb.com> Co-authored-by: Alex Li <alex.li@mongodb.com> Co-authored-by: Ryan Berryhill <ryan.berryhill@mongodb.com> Co-authored-by: Guillaume Racicot <guillaume.racicot@mongodb.com> GitOrigin-RevId: c30d29c3fb72d0e33f5af5a5e2639597c16e7c6e
This commit is contained in:
parent
442ae3df3b
commit
b0a421a6ae
@ -57,10 +57,9 @@ namespace mongo {
|
||||
// Used by `logScopedDebugInfo` below to determine if we should log anything.
|
||||
Atomic<bool> shouldLogScopedDebugInfoInAssertUtil{true};
|
||||
|
||||
void setDiagnosticLoggingInAssertUtil(bool newVal) {
|
||||
shouldLogScopedDebugInfoInAssertUtil.store(newVal);
|
||||
}
|
||||
namespace {
|
||||
Atomic<bool> gScopedDebugInfoStackEnabled{true};
|
||||
|
||||
void logScopedDebugInfo() {
|
||||
if (!shouldLogScopedDebugInfoInAssertUtil.load()) {
|
||||
return;
|
||||
@ -97,6 +96,18 @@ MONGO_COMPILER_NORETURN void callAbort() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void setDiagnosticLoggingInAssertUtil(bool newVal) {
|
||||
shouldLogScopedDebugInfoInAssertUtil.store(newVal);
|
||||
}
|
||||
|
||||
void setScopedDebugInfoStackEnabled(bool newVal) {
|
||||
gScopedDebugInfoStackEnabled.store(newVal);
|
||||
}
|
||||
|
||||
bool getScopedDebugInfoStackEnabled() {
|
||||
return gScopedDebugInfoStackEnabled.loadRelaxed();
|
||||
}
|
||||
|
||||
AssertionCount assertionCount;
|
||||
|
||||
AssertionCount::AssertionCount() : regular(0), warning(0), msg(0), user(0), rollovers(0) {}
|
||||
@ -367,6 +378,8 @@ std::vector<std::string> ScopedDebugInfoStack::getAll() {
|
||||
|
||||
std::vector<std::string> r;
|
||||
r.reserve(_stack.size());
|
||||
const auto initialData = _stack.data();
|
||||
const auto initialSize = _stack.size();
|
||||
for (const auto& e : _stack) {
|
||||
try {
|
||||
r.push_back(e->toString());
|
||||
@ -376,6 +389,8 @@ std::vector<std::string> ScopedDebugInfoStack::getAll() {
|
||||
"label"_attr = e->label(),
|
||||
"error"_attr = describeActiveException());
|
||||
}
|
||||
invariant(_stack.data() == initialData);
|
||||
invariant(_stack.size() == initialSize);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
@ -64,6 +64,12 @@ namespace MONGO_MOD_PUB mongo {
|
||||
*/
|
||||
MONGO_MOD_PRIVATE void setDiagnosticLoggingInAssertUtil(bool newVal);
|
||||
|
||||
/**
|
||||
* Whether ScopedDebugInfoStack is ever accessed by ScopedDebugInfo.
|
||||
*/
|
||||
MONGO_MOD_PRIVATE void setScopedDebugInfoStackEnabled(bool newVal);
|
||||
MONGO_MOD_PRIVATE bool getScopedDebugInfoStackEnabled();
|
||||
|
||||
class MONGO_MOD_NEEDS_REPLACEMENT AssertionCount {
|
||||
public:
|
||||
AssertionCount();
|
||||
@ -142,7 +148,6 @@ public:
|
||||
return _status.extraInfo<ErrorDetail>();
|
||||
}
|
||||
|
||||
// TODO(modularity): We should provide a way for modules to own their options parsers.
|
||||
MONGO_MOD_NEEDS_REPLACEMENT static inline AtomicWord<bool> traceExceptions{false};
|
||||
|
||||
/**
|
||||
@ -876,11 +881,34 @@ public:
|
||||
virtual StringData label() const = 0;
|
||||
};
|
||||
|
||||
void push(const Rec* rec) {
|
||||
_stack.push_back(rec);
|
||||
ScopedDebugInfoStack() {
|
||||
_stack.reserve(64);
|
||||
}
|
||||
void pop() {
|
||||
|
||||
~ScopedDebugInfoStack() {
|
||||
_checkConsistentSize();
|
||||
invariant(_stack.empty());
|
||||
}
|
||||
|
||||
void push(const Rec* rec) {
|
||||
invariant(_loggingDepth == 0);
|
||||
_checkConsistentSize();
|
||||
_stack.push_back(rec);
|
||||
++_pushes;
|
||||
}
|
||||
|
||||
const Rec* pop() {
|
||||
invariant(_loggingDepth == 0);
|
||||
_checkConsistentSize();
|
||||
invariant(!_stack.empty());
|
||||
const Rec* popped = std::exchange(_stack.back(), {});
|
||||
_stack.pop_back();
|
||||
++_pops;
|
||||
return popped;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _stack.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -893,8 +921,16 @@ public:
|
||||
std::vector<std::string> getAll();
|
||||
|
||||
private:
|
||||
void _checkConsistentSize() const {
|
||||
auto sz = _stack.size();
|
||||
invariant(_pushes == sz + _pops,
|
||||
fmt::format("pushes={}, pops={}, size={}", _pushes, _pops, sz));
|
||||
}
|
||||
|
||||
std::vector<const Rec*> _stack;
|
||||
int _loggingDepth = 0;
|
||||
size_t _pushes = 0;
|
||||
size_t _pops = 0;
|
||||
};
|
||||
|
||||
/** Each thread has its own stack of scoped debug info. */
|
||||
@ -930,18 +966,25 @@ inline ScopedDebugInfoStack& scopedDebugInfoStack() {
|
||||
template <typename T>
|
||||
class ScopedDebugInfo {
|
||||
public:
|
||||
ScopedDebugInfo(
|
||||
StringData label,
|
||||
T v,
|
||||
error_details::ScopedDebugInfoStack* stack = &error_details::scopedDebugInfoStack())
|
||||
ScopedDebugInfo(StringData label, T v)
|
||||
: ScopedDebugInfo{label, std::move(v), _defaultStack()} {}
|
||||
|
||||
ScopedDebugInfo(StringData label, T v, error_details::ScopedDebugInfoStack* stack)
|
||||
: label(label), v(std::move(v)), stack(stack) {
|
||||
stack->push(&rec);
|
||||
if (stack) {
|
||||
stack->push(&rec);
|
||||
}
|
||||
}
|
||||
|
||||
~ScopedDebugInfo() {
|
||||
stack->pop();
|
||||
if (stack) {
|
||||
auto popped = stack->pop();
|
||||
invariant(popped == &rec);
|
||||
}
|
||||
}
|
||||
ScopedDebugInfo(const ScopedDebugInfo&) noexcept = delete;
|
||||
ScopedDebugInfo& operator=(const ScopedDebugInfo&) noexcept = delete;
|
||||
|
||||
ScopedDebugInfo(const ScopedDebugInfo&) = delete;
|
||||
ScopedDebugInfo& operator=(const ScopedDebugInfo&) = delete;
|
||||
|
||||
private:
|
||||
struct ThisRec : error_details::ScopedDebugInfoStack::Rec {
|
||||
@ -955,6 +998,12 @@ private:
|
||||
const ScopedDebugInfo* owner;
|
||||
};
|
||||
|
||||
static error_details::ScopedDebugInfoStack* _defaultStack() {
|
||||
if (!getScopedDebugInfoStackEnabled())
|
||||
return {};
|
||||
return &error_details::scopedDebugInfoStack();
|
||||
}
|
||||
|
||||
StringData label;
|
||||
T v;
|
||||
error_details::ScopedDebugInfoStack* stack;
|
||||
|
||||
@ -41,11 +41,13 @@ MONGO_INITIALIZER(SetUpDiagnosticLoggingStatus)(InitializerContext*) {
|
||||
bool signalHandlerLoggingVal = signalHandlerUsesDiagnosticLogging.load();
|
||||
setDiagnosticLoggingInSignalHandlers(startUpVal && signalHandlerLoggingVal);
|
||||
setDiagnosticLoggingInAssertUtil(startUpVal);
|
||||
setScopedDebugInfoStackEnabled(startUpVal);
|
||||
}
|
||||
|
||||
Status onUpdateEnableDiagnosticLogging(bool newValue) {
|
||||
setDiagnosticLoggingInSignalHandlers(newValue);
|
||||
setDiagnosticLoggingInAssertUtil(newValue);
|
||||
setScopedDebugInfoStackEnabled(newValue);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
|
||||
@ -802,5 +802,20 @@ TEST(AssertUtils, FailuresAreNotConstexpr) {
|
||||
}()));
|
||||
}
|
||||
|
||||
TEST(ScopedDebugInfoStack, Enabled) {
|
||||
ASSERT(getScopedDebugInfoStackEnabled());
|
||||
ASSERT_EQ(error_details::scopedDebugInfoStack().size(), 0);
|
||||
ScopedDebugInfo scopedInfo("test", "hello");
|
||||
ASSERT_EQ(error_details::scopedDebugInfoStack().size(), 1);
|
||||
}
|
||||
|
||||
TEST(ScopedDebugInfoStack, Disabled) {
|
||||
RAIIServerParameterControllerForTest knobController("enableDiagnosticLogging", false);
|
||||
ASSERT(!getScopedDebugInfoStackEnabled());
|
||||
ASSERT_EQ(error_details::scopedDebugInfoStack().size(), 0);
|
||||
ScopedDebugInfo scopedInfo("test", "hello");
|
||||
ASSERT_EQ(error_details::scopedDebugInfoStack().size(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mongo
|
||||
|
||||
Loading…
Reference in New Issue
Block a user