summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2017-12-21 17:50:40 -0500
committerBenety Goh <benety@mongodb.com>2017-12-26 14:49:32 -0500
commit9348c9f11174019ee1be93b25c3f44d070194472 (patch)
tree520fed504f028dc164a08bd22484b43de35d7202
parent7cb2563388f77c7f0fea72811f512321f23096bd (diff)
downloadmongo-9348c9f11174019ee1be93b25c3f44d070194472.tar.gz
SERVER-32369 evaluate invariant message before passing to invariantFailedWithMsg()
-rw-r--r--src/mongo/util/assert_util.cpp7
-rw-r--r--src/mongo/util/assert_util_test.cpp25
-rw-r--r--src/mongo/util/invariant.h16
3 files changed, 43 insertions, 5 deletions
diff --git a/src/mongo/util/assert_util.cpp b/src/mongo/util/assert_util.cpp
index 24f2258a348..72cc16ab515 100644
--- a/src/mongo/util/assert_util.cpp
+++ b/src/mongo/util/assert_util.cpp
@@ -141,6 +141,13 @@ NOINLINE_DECL void invariantFailedWithMsg(const char* expr,
std::abort();
}
+NOINLINE_DECL void invariantFailedWithMsg(const char* expr,
+ const std::string& msg,
+ const char* file,
+ unsigned line) noexcept {
+ invariantFailedWithMsg(expr, msg.c_str(), file, line);
+}
+
NOINLINE_DECL void invariantOKFailed(const char* expr,
const Status& status,
const char* file,
diff --git a/src/mongo/util/assert_util_test.cpp b/src/mongo/util/assert_util_test.cpp
index 315e4200d8b..841dc37ba00 100644
--- a/src/mongo/util/assert_util_test.cpp
+++ b/src/mongo/util/assert_util_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/unittest/death_test.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/assert_util.h"
+#include "mongo/util/mongoutils/str.h"
namespace mongo {
namespace {
@@ -219,5 +220,29 @@ DEATH_TEST(MassertionTerminationTest, msgasserted, "Terminating with msgasserted
msgasserted(40215, "Terminating with msgasserted");
}
+// invariant and its friends
+DEATH_TEST(InvariantTerminationTest, invariant, "Invariant failure false " __FILE__) {
+ invariant(false);
+}
+
+DEATH_TEST(InvariantTerminationTest, invariantOK, "Terminating with invariantOK") {
+ invariantOK(Status(ErrorCodes::InternalError, "Terminating with invariantOK"));
+}
+
+DEATH_TEST(InvariantTerminationTest,
+ invariantWithStringLiteralMsg,
+ "Terminating with string literal invariant message") {
+ const char* msg = "Terminating with string literal invariant message";
+ invariant(false, msg);
+}
+
+DEATH_TEST(InvariantTerminationTest,
+ invariantWithStdStringMsg,
+ "Terminating with std::string invariant message: 12345") {
+ const std::string msg = str::stream() << "Terminating with std::string invariant message: "
+ << 12345;
+ invariant(false, msg);
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/util/invariant.h b/src/mongo/util/invariant.h
index d62d7a3235e..edd2f210ce2 100644
--- a/src/mongo/util/invariant.h
+++ b/src/mongo/util/invariant.h
@@ -28,6 +28,7 @@
#pragma once
#include <boost/preprocessor/facilities/overload.hpp>
+#include <string>
#include "mongo/platform/compiler.h"
#include "mongo/util/debug_util.h"
@@ -66,6 +67,11 @@ MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr,
const char* file,
unsigned line) noexcept;
+MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr,
+ const std::string& msg,
+ const char* file,
+ unsigned line) noexcept;
+
// This invariant overload accepts a condition and a message, to be logged if the condition is
// false.
//
@@ -73,11 +79,11 @@ MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr,
//
// 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__); \
- } \
+#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.