Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Unified Diff: base/logging_unittest.cc

Issue 2288473002: Implement Dump-on-DCHECK (via a new LogSeverity). (Closed)
Patch Set: Pull the Official Windows build default in, and rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/logging.cc ('k') | base/syslog_logging.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/logging_unittest.cc
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index f41cce2f43b390fa9603a14f3f689fe87d0dcb33..6a18a109ff71efe6f530491786696e56d984d4fe 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/compiler_specific.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -16,11 +17,11 @@ namespace {
using ::testing::Return;
// Needs to be global since log assert handlers can't maintain state.
-int log_sink_call_count = 0;
+int g_log_sink_call_count = 0;
#if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
void LogSink(const std::string& str) {
- ++log_sink_call_count;
+ ++g_log_sink_call_count;
}
#endif
@@ -33,7 +34,7 @@ class LogStateSaver {
~LogStateSaver() {
SetMinLogLevel(old_min_log_level_);
SetLogAssertHandler(NULL);
- log_sink_call_count = 0;
+ g_log_sink_call_count = 0;
}
private:
@@ -86,10 +87,12 @@ TEST_F(LoggingTest, BasicLogging) {
}
TEST_F(LoggingTest, LogIsOn) {
-#if defined(NDEBUG)
- const bool kDfatalIsFatal = false;
+#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
+ const bool kDfatalIsActive = true;
+#elif defined(NDEBUG)
+ const bool kDfatalIsActive = false;
#else // defined(NDEBUG)
- const bool kDfatalIsFatal = true;
+ const bool kDfatalIsActive = true;
#endif // defined(NDEBUG)
SetMinLogLevel(LOG_INFO);
@@ -119,7 +122,9 @@ TEST_F(LoggingTest, LogIsOn) {
EXPECT_FALSE(LOG_IS_ON(WARNING));
EXPECT_FALSE(LOG_IS_ON(ERROR));
EXPECT_TRUE(LOG_IS_ON(FATAL));
- EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
+ EXPECT_EQ(kDfatalIsActive, LOG_IS_ON(DFATAL));
+
+ EXPECT_EQ(DCHECK_IS_ON() != 0, LOG_IS_ON(DCHECK));
}
TEST_F(LoggingTest, LoggingIsLazyBySeverity) {
@@ -191,7 +196,7 @@ TEST_F(LoggingTest, CheckStreamsAreLazy) {
#endif
TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
-#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+#if DCHECK_IS_ON()
int debug_only_variable = 1;
#endif
// These should avoid emitting references to |debug_only_variable|
@@ -217,6 +222,7 @@ TEST_F(LoggingTest, DcheckStreamsAreLazy) {
#endif
}
+#if !defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
void DcheckEmptyFunction1() {
// Provide a body so that Release builds do not cause the compiler to
// optimize DcheckEmptyFunction1 and DcheckEmptyFunction2 as a single
@@ -242,33 +248,33 @@ TEST_F(LoggingTest, Dcheck) {
EXPECT_TRUE(DLOG_IS_ON(DCHECK));
#endif
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
DCHECK(false);
- EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
DPCHECK(false);
- EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
DCHECK_EQ(0, 1);
- EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, g_log_sink_call_count);
// Test DCHECK on std::nullptr_t
- log_sink_call_count = 0;
+ g_log_sink_call_count = 0;
const void* p_null = nullptr;
const void* p_not_null = &p_null;
DCHECK_EQ(p_null, nullptr);
DCHECK_EQ(nullptr, p_null);
DCHECK_NE(p_not_null, nullptr);
DCHECK_NE(nullptr, p_not_null);
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
// Test DCHECK on a scoped enum.
enum class Animal { DOG, CAT };
DCHECK_EQ(Animal::DOG, Animal::DOG);
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
DCHECK_EQ(Animal::DOG, Animal::CAT);
- EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
// Test DCHECK on functions and function pointers.
- log_sink_call_count = 0;
+ g_log_sink_call_count = 0;
struct MemberFunctions {
void MemberFunction1() {
// See the comment in DcheckEmptyFunction1().
@@ -282,16 +288,17 @@ TEST_F(LoggingTest, Dcheck) {
void (*fp2)() = DcheckEmptyFunction2;
void (*fp3)() = DcheckEmptyFunction1;
DCHECK_EQ(fp1, fp3);
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1);
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2);
- EXPECT_EQ(0, log_sink_call_count);
+ EXPECT_EQ(0, g_log_sink_call_count);
DCHECK_EQ(fp1, fp2);
- EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1);
- EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
+ EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
}
+#endif // !defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
TEST_F(LoggingTest, DcheckReleaseBehavior) {
int some_variable = 1;
@@ -326,6 +333,37 @@ TEST_F(LoggingTest, CheckEqStatements) {
CHECK_EQ(false, true); // Unreached.
}
+namespace {
+
+int g_fake_dump_without_crashing_count = 0;
+void FakeDumpWithoutCrashing() {
+ g_fake_dump_without_crashing_count++;
+}
+
+} // namespace
+
+TEST_F(LoggingTest, LogMessageDump) {
+ // Replace the dump-without-crashing function, to test.
+ base::debug::SetDumpWithoutCrashingFunction(&FakeDumpWithoutCrashing);
+
+ // LOG_DUMP is an internal severity level for use by dump-on-DCHECK, so
+ // we must call LogMessage() directly, rather than using LOG(DUMP).
+ LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string);
+ EXPECT_EQ(1, g_fake_dump_without_crashing_count);
+ LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string);
+ EXPECT_EQ(1, g_fake_dump_without_crashing_count);
+
+#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
+ EXPECT_EQ(LOG_DUMP, LOG_DFATAL);
+ EXPECT_EQ(LOG_DUMP, LOG_DCHECK);
+#else // defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
+ EXPECT_NE(LOG_DUMP, LOG_DFATAL);
+ EXPECT_NE(LOG_DUMP, LOG_DCHECK);
+#endif // defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
+
+ base::debug::SetDumpWithoutCrashingFunction(nullptr);
+}
+
// Test that defining an operator<< for a type in a namespace doesn't prevent
// other code in that namespace from calling the operator<<(ostream, wstring)
// defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
« no previous file with comments | « base/logging.cc ('k') | base/syslog_logging.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698