Index: base/logging.h |
diff --git a/base/logging.h b/base/logging.h |
index de95716fea2104e631eafd5bef50eb73d09baac6..ac014b78dc454f0a4f06aba1e558806c55e02421 100644 |
--- a/base/logging.h |
+++ b/base/logging.h |
@@ -335,7 +335,7 @@ const LogSeverity LOG_FATAL = 3; |
const LogSeverity LOG_NUM_SEVERITIES = 4; |
// LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode |
-#if defined(NDEBUG) |
+#if defined(NDEBUG) || defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
const LogSeverity LOG_DFATAL = LOG_ERROR; |
#else |
const LogSeverity LOG_DFATAL = LOG_FATAL; |
@@ -808,6 +808,22 @@ const LogSeverity LOG_DCHECK = LOG_INFO; |
#if DCHECK_IS_ON() |
+#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+// DCHECK is configured to dump-without-crashing, rather than logging. |
+// Since we only intend to enable this in official builds, we follow the |
+// example of CHECK_OP etc in official builds, and strip out logging. |
+// See crbug.com/596231. |
+ |
+BASE_EXPORT void DCheckDumpWithoutCrashingOnce(); |
+ |
+#define DCHECK(condition) \ |
+ !(condition) ? ::logging::DCheckDumpWithoutCrashingOnce() \ |
+ : EAT_STREAM_PARAMETERS |
+ |
+#define DPCHECK(condition) DCHECK(condition) |
+ |
+#else // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+ |
#define DCHECK(condition) \ |
LAZY_STREAM(LOG_STREAM(DCHECK), !ANALYZER_ASSUME_TRUE(condition)) \ |
<< "Check failed: " #condition ". " |
@@ -815,6 +831,8 @@ const LogSeverity LOG_DCHECK = LOG_INFO; |
LAZY_STREAM(PLOG_STREAM(DCHECK), !ANALYZER_ASSUME_TRUE(condition)) \ |
<< "Check failed: " #condition ". " |
+#endif // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+ |
#else // DCHECK_IS_ON() |
#define DCHECK(condition) \ |
@@ -832,6 +850,19 @@ const LogSeverity LOG_DCHECK = LOG_INFO; |
// DCHECK_EQ(2, a); |
#if DCHECK_IS_ON() |
+#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+// DCHECK is configured to dump-without-crashing, rather than logging. |
+// DCHECK_OP builds on DCHECK in this case (thereby inheriting the stripping |
+// of any << logged output. We use Check[op]Impl() for the comparison rather |
+// that comparing val1 and val2 directly because it ensures that the values' |
+// operator<< implementation is referenced, while coping with unnamed enums. |
+// See crbug.com/596231. |
+ |
+#define DCHECK_OP(name, op, val1, val2) \ |
+ DCHECK(::logging::Check##name##Impl((val1), (val2), "") == nullptr) |
+ |
+#else // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+ |
#define DCHECK_OP(name, op, val1, val2) \ |
switch (0) case 0: default: \ |
if (::logging::CheckOpResult true_if_passed = \ |
@@ -843,6 +874,8 @@ const LogSeverity LOG_DCHECK = LOG_INFO; |
::logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \ |
true_if_passed.message()).stream() |
+#endif // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
+ |
#else // DCHECK_IS_ON() |
// When DCHECKs aren't enabled, DCHECK_OP still needs to reference operator<< |