diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/executor/connection_pool.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/assert_util.cpp | 11 | ||||
-rw-r--r-- | src/mongo/util/invariant.h | 41 |
3 files changed, 50 insertions, 6 deletions
diff --git a/src/mongo/executor/connection_pool.cpp b/src/mongo/executor/connection_pool.cpp index 880edda2879..7830c1425a2 100644 --- a/src/mongo/executor/connection_pool.cpp +++ b/src/mongo/executor/connection_pool.cpp @@ -312,7 +312,9 @@ void ConnectionPool::returnConnection(ConnectionInterface* conn) { auto iter = _pools.find(conn->getHostAndPort()); - invariant(iter != _pools.end()); + invariant(iter != _pools.end(), + str::stream() << "Tried to return connection but no pool found for " + << conn->getHostAndPort()); iter->second->runWithActiveClient(std::move(lk), [&](decltype(lk) lk) { iter->second->returnConnection(conn, std::move(lk)); diff --git a/src/mongo/util/assert_util.cpp b/src/mongo/util/assert_util.cpp index 29a0019dc35..24f2258a348 100644 --- a/src/mongo/util/assert_util.cpp +++ b/src/mongo/util/assert_util.cpp @@ -130,6 +130,17 @@ NOINLINE_DECL void invariantFailed(const char* expr, const char* file, unsigned std::abort(); } +NOINLINE_DECL void invariantFailedWithMsg(const char* expr, + const char* msg, + const char* file, + unsigned line) noexcept { + severe() << "Invariant failure " << expr << " " << msg << " " << file << ' ' << dec << line + << endl; + breakpoint(); + severe() << "\n\n***aborting after invariant() failure\n\n" << endl; + std::abort(); +} + NOINLINE_DECL void invariantOKFailed(const char* expr, const Status& status, const char* file, diff --git a/src/mongo/util/invariant.h b/src/mongo/util/invariant.h index 0851ade981d..d62d7a3235e 100644 --- a/src/mongo/util/invariant.h +++ b/src/mongo/util/invariant.h @@ -27,6 +27,8 @@ #pragma once +#include <boost/preprocessor/facilities/overload.hpp> + #include "mongo/platform/compiler.h" #include "mongo/util/debug_util.h" @@ -46,20 +48,49 @@ MONGO_COMPILER_NORETURN void invariantFailed(const char* expr, const char* file, unsigned line) noexcept; -#define MONGO_invariant(_Expression) \ +// This overload is our legacy invariant, which just takes a condition to test. +// +// ex) invariant(!condition); +// +// Invariant failure !condition some/file.cpp 528 +// +#define MONGO_invariant_1(_Expression) \ do { \ if (MONGO_unlikely(!(_Expression))) { \ ::mongo::invariantFailed(#_Expression, __FILE__, __LINE__); \ } \ } while (false) -#define invariant MONGO_invariant +MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr, + const char* msg, + const char* file, + unsigned line) noexcept; + +// This invariant overload accepts a condition and a message, to be logged if the condition is +// false. +// +// ex) invariant(!condition, "hello!"); +// +// Invariant failure !condition "hello!" some/file.cpp 528 +// +#define MONGO_invariant_2(_Expression, _Message) \ + do { \ + if (MONGO_unlikely(!(_Expression))) { \ + ::mongo::invariantFailedWithMsg(#_Expression, #_Message, __FILE__, __LINE__); \ + } \ + } while (false) + +// This helper macro is necessary to make the __VAR_ARGS__ expansion work properly on MSVC. +#define MONGO_expand(x) x + +#define invariant(...) \ + MONGO_expand(MONGO_expand(BOOST_PP_OVERLOAD(MONGO_invariant_, __VA_ARGS__))(__VA_ARGS__)) // Behaves like invariant in debug builds and is compiled out in release. Use for checks, which can // potentially be slow or on a critical path. -#define MONGO_dassert(x) \ - if (kDebugBuild) \ - invariant(x) +#define MONGO_dassert(...) \ + if (kDebugBuild) \ + invariant(__VA_ARGS__) #define dassert MONGO_dassert |