diff options
author | Kevin Pulo <kevin.pulo@mongodb.com> | 2020-10-26 17:11:18 +1100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-02 09:58:44 +0000 |
commit | 7d8e64df2d2d56a821f638ef88aa619403d03d31 (patch) | |
tree | 6ada2d481c56b9754ec7848caf146cd94149148f /src/mongo/util/assert_util.h | |
parent | 4d2dea00415bf02d2b32d0474c93d251ce6568cc (diff) | |
download | mongo-7d8e64df2d2d56a821f638ef88aa619403d03d31.tar.gz |
SERVER-44570 Add tripwire assertions (tassert)
Diffstat (limited to 'src/mongo/util/assert_util.h')
-rw-r--r-- | src/mongo/util/assert_util.h | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/mongo/util/assert_util.h b/src/mongo/util/assert_util.h index f1e54d2a7ce..0e2558cf093 100644 --- a/src/mongo/util/assert_util.h +++ b/src/mongo/util/assert_util.h @@ -39,6 +39,7 @@ #include "mongo/platform/source_location.h" #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/debug_util.h" +#include "mongo/util/exit_code.h" #define MONGO_INCLUDE_INVARIANT_H_WHITELISTED #include "mongo/util/invariant.h" @@ -56,6 +57,7 @@ public: AtomicWord<int> warning; AtomicWord<int> msg; AtomicWord<int> user; + AtomicWord<int> tripwire; AtomicWord<int> rollovers; }; @@ -472,6 +474,59 @@ inline void internalAssertWithLocation(SourceLocationHolder loc, StatusWith<T>&& } /** + * "tripwire/test assert". Like uassert, but with a deferred-fatality tripwire that gets + * checked prior to normal shutdown. Used to ensure that this assertion will both fail the + * operation and also cause a test suite failure. + */ +#define tassert(...) ::mongo::tassertWithLocation(MONGO_SOURCE_LOCATION(), __VA_ARGS__) + +MONGO_COMPILER_NORETURN void tassertFailedWithLocation(SourceLocationHolder loc, + const Status& status); + +#define tasserted(...) ::mongo::tassertFailedWithLocation(MONGO_SOURCE_LOCATION(), __VA_ARGS__) + +MONGO_COMPILER_NORETURN inline void tassertFailedWithLocation(SourceLocationHolder loc, + int msgid, + const std::string& msg) { + tassertFailedWithLocation(std::move(loc), Status(ErrorCodes::Error(msgid), msg)); +} + +void tassertWithLocation(SourceLocationHolder loc, const Status& status); + +inline void tassertWithLocation(SourceLocationHolder loc, Status&& status) { + tassertWithLocation(std::move(loc), status); +} + +inline void tassertWithLocation(SourceLocationHolder loc, + int msgid, + const std::string& msg, + bool expr) { + if (MONGO_unlikely(!expr)) + tassertWithLocation(std::move(loc), Status(ErrorCodes::Error(msgid), msg)); +} + +template <typename T> +inline void tassertWithLocation(SourceLocationHolder loc, const StatusWith<T>& sw) { + tassertWithLocation(std::move(loc), sw.getStatus()); +} + +template <typename T> +inline void tassertWithLocation(SourceLocationHolder loc, StatusWith<T>&& sw) { + tassertWithLocation(std::move(loc), sw); +} + +/** + * Handle tassert failures during exit with a given exit code. + * + * If the exit code is success (ie. EXIT_CLEAN, EXIT_SUCCESS, or 0) and there have been any tassert + * failures, then abort the process. + * + * Otherwise, if the exit code is an error, then just log the number of tassert failures (and then + * continue exiting with that exit code). + */ +void checkForTripwireAssertions(int code = EXIT_CLEAN); + +/** * verify is deprecated. It is like invariant() in debug builds and massert() in release builds. */ #define verify(expression) MONGO_verify(expression) @@ -642,3 +697,8 @@ Status exceptionToStatus() noexcept; */ #define MONGO_UNREACHABLE ::mongo::invariantFailed("Hit a MONGO_UNREACHABLE!", __FILE__, __LINE__); + +#define MONGO_UNREACHABLE_TASSERT(msgid) \ + ::mongo::tassertFailedWithLocation( \ + MONGO_SOURCE_LOCATION(), \ + Status(ErrorCodes::Error(msgid), "Hit a MONGO_UNREACHABLE_TASSERT!")); |