Index: base/logging_unittest.cc |
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc |
index f41cce2f43b390fa9603a14f3f689fe87d0dcb33..5f9574467b06216df4c87f643a29a79df97db5ab 100644 |
--- a/base/logging_unittest.cc |
+++ b/base/logging_unittest.cc |
@@ -5,10 +5,16 @@ |
#include "base/compiler_specific.h" |
#include "base/logging.h" |
#include "base/macros.h" |
+#include "base/rand_util.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+#if defined(OS_WIN) |
+#include <windows.h> |
+#include <excpt.h> |
+#endif // OS_WIN |
+ |
namespace logging { |
namespace { |
@@ -190,6 +196,64 @@ TEST_F(LoggingTest, CheckStreamsAreLazy) { |
#endif |
+#if defined(OFFICIAL_BUILD) && defined(OS_WIN) |
+__declspec(noinline) void CheckContainingFunc(uint64_t x, uint64_t y, int z) { |
Will Harris
2017/02/02 01:21:06
not sure here (base owner might know) but I think
scottmg
2017/02/02 01:41:23
Done.
|
+ if (z == 1) |
+ CHECK(!x); |
+ if (z == 2) |
+ CHECK(!y); |
+ if (z == 3) |
+ CHECK(false); |
+} |
+ |
+int GetCheckExceptionData(EXCEPTION_POINTERS* p, DWORD* code, void** addr) { |
+ *code = p->ExceptionRecord->ExceptionCode; |
+ *addr = p->ExceptionRecord->ExceptionAddress; |
+ return EXCEPTION_EXECUTE_HANDLER; |
+} |
+ |
+TEST_F(LoggingTest, CheckCausesDistinctBreakpoints) { |
+ uint64_t x = base::RandUint64(); |
Will Harris
2017/02/02 01:21:06
this can return 0, so the test can fail with a ver
scottmg
2017/02/02 01:41:24
Meh. Done.
|
+ uint64_t y = base::RandUint64(); |
+ DWORD code1 = 0; |
+ DWORD code2 = 0; |
+ DWORD code3 = 0; |
+ void* addr1 = nullptr; |
+ void* addr2 = nullptr; |
+ void* addr3 = nullptr; |
+ |
+ // Record the exception code and addresses. |
+ __try { |
+ CheckContainingFunc(x, y, 1); |
+ } __except ( |
+ GetCheckExceptionData(GetExceptionInformation(), &code1, &addr1)) { |
+ } |
+ |
+ __try { |
+ CheckContainingFunc(x, y, 2); |
+ } __except ( |
+ GetCheckExceptionData(GetExceptionInformation(), &code2, &addr2)) { |
+ } |
+ |
+ __try { |
+ CheckContainingFunc(x, y, 3); |
+ } __except ( |
+ GetCheckExceptionData(GetExceptionInformation(), &code3, &addr3)) { |
+ } |
+ |
+ // Ensure that the exception codes are correct (in particular, breakpoints, |
+ // not access violations). |
+ EXPECT_EQ(STATUS_BREAKPOINT, code1); |
+ EXPECT_EQ(STATUS_BREAKPOINT, code2); |
+ EXPECT_EQ(STATUS_BREAKPOINT, code3); |
+ |
+ // Ensure that none of the CHECKs are colocated. |
+ EXPECT_NE(addr1, addr2); |
+ EXPECT_NE(addr1, addr3); |
+ EXPECT_NE(addr2, addr3); |
+} |
+#endif // OFFICIAL_BUILD && OS_WIN |
+ |
TEST_F(LoggingTest, DebugLoggingReleaseBehavior) { |
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
int debug_only_variable = 1; |