summaryrefslogtreecommitdiff
path: root/src/mongo/util/assert_util.h
diff options
context:
space:
mode:
authorKevin Pulo <kevin.pulo@mongodb.com>2020-10-26 17:11:18 +1100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-02 09:58:44 +0000
commit7d8e64df2d2d56a821f638ef88aa619403d03d31 (patch)
tree6ada2d481c56b9754ec7848caf146cd94149148f /src/mongo/util/assert_util.h
parent4d2dea00415bf02d2b32d0474c93d251ce6568cc (diff)
downloadmongo-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.h60
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!"));