Add ability to disable detailed error message in RTC_CHECKs

Bug: webrtc:11133
Change-Id: I989654f1fb97b476a17956d69ee374406439ea8f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160653
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29952}
diff --git a/BUILD.gn b/BUILD.gn
index 5e9f832..f81ad5f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -123,6 +123,10 @@
     defines += [ "WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS" ]
   }
 
+  if (rtc_disable_check_msg) {
+    defines += [ "RTC_DISABLE_CHECK_MSG" ]
+  }
+
   # Some tests need to declare their own trace event handlers. If this define is
   # not set, the first time TRACE_EVENT_* is called it will store the return
   # value for the current handler in an static variable, so that subsequent
diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn
index 7c5d8b0..71700007 100644
--- a/common_audio/BUILD.gn
+++ b/common_audio/BUILD.gn
@@ -366,6 +366,7 @@
       "../rtc_base/system:arch",
       "../system_wrappers:cpu_features_api",
       "../test:fileutils",
+      "../test:rtc_expect_death",
       "../test:test_main",
       "../test:test_support",
       "//testing/gtest",
diff --git a/common_audio/channel_buffer_unittest.cc b/common_audio/channel_buffer_unittest.cc
index 7d45e7c..8ec4234 100644
--- a/common_audio/channel_buffer_unittest.cc
+++ b/common_audio/channel_buffer_unittest.cc
@@ -11,6 +11,7 @@
 #include "common_audio/channel_buffer.h"
 
 #include "test/gtest.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 namespace webrtc {
 
@@ -54,12 +55,12 @@
 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
 TEST(ChannelBufferTest, SetNumChannelsDeathTest) {
   ChannelBuffer<float> chb(kNumFrames, kMono);
-  EXPECT_DEATH(chb.set_num_channels(kStereo), "num_channels");
+  RTC_EXPECT_DEATH(chb.set_num_channels(kStereo), "num_channels");
 }
 
 TEST(IFChannelBufferTest, SetNumChannelsDeathTest) {
   IFChannelBuffer ifchb(kNumFrames, kMono);
-  EXPECT_DEATH(ifchb.ibuf()->set_num_channels(kStereo), "num_channels");
+  RTC_EXPECT_DEATH(ifchb.ibuf()->set_num_channels(kStereo), "num_channels");
 }
 #endif
 
diff --git a/common_audio/resampler/push_resampler_unittest.cc b/common_audio/resampler/push_resampler_unittest.cc
index 8b0d548..61b9725 100644
--- a/common_audio/resampler/push_resampler_unittest.cc
+++ b/common_audio/resampler/push_resampler_unittest.cc
@@ -12,6 +12,7 @@
 
 #include "rtc_base/checks.h"  // RTC_DCHECK_IS_ON
 #include "test/gtest.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 // Quality testing of PushResampler is handled through output_mixer_unittest.cc.
 
@@ -32,19 +33,20 @@
 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
 TEST(PushResamplerTest, VerifiesBadInputParameters1) {
   PushResampler<int16_t> resampler;
-  EXPECT_DEATH(resampler.InitializeIfNeeded(-1, 16000, 1),
-               "src_sample_rate_hz");
+  RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(-1, 16000, 1),
+                   "src_sample_rate_hz");
 }
 
 TEST(PushResamplerTest, VerifiesBadInputParameters2) {
   PushResampler<int16_t> resampler;
-  EXPECT_DEATH(resampler.InitializeIfNeeded(16000, -1, 1),
-               "dst_sample_rate_hz");
+  RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(16000, -1, 1),
+                   "dst_sample_rate_hz");
 }
 
 TEST(PushResamplerTest, VerifiesBadInputParameters3) {
   PushResampler<int16_t> resampler;
-  EXPECT_DEATH(resampler.InitializeIfNeeded(16000, 16000, 0), "num_channels");
+  RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(16000, 16000, 0),
+                   "num_channels");
 }
 
 #endif
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index deb685f..4b9d20b 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -2123,6 +2123,7 @@
       "../../test:audio_codec_mocks",
       "../../test:field_trial",
       "../../test:fileutils",
+      "../../test:rtc_expect_death",
       "../../test:rtp_test_utils",
       "../../test:test_common",
       "../../test:test_support",
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index ab84c78..9dca4cd 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -54,6 +54,7 @@
 #include "test/mock_audio_decoder.h"
 #include "test/mock_audio_encoder.h"
 #include "test/testsupport/file_utils.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 using ::testing::_;
 using ::testing::AtLeast;
@@ -272,8 +273,8 @@
 TEST_F(AudioCodingModuleTestOldApi, FailOnZeroDesiredFrequency) {
   AudioFrame audio_frame;
   bool muted;
-  EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted),
-               "dst_sample_rate_hz");
+  RTC_EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted),
+                   "dst_sample_rate_hz");
 }
 #endif
 
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
index 6dda862..085deb1 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
@@ -18,6 +18,7 @@
 #include "rtc_base/numerics/safe_conversions.h"
 #include "test/gtest.h"
 #include "test/mock_audio_encoder.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 using ::testing::_;
 using ::testing::InSequence;
@@ -441,7 +442,7 @@
   }
 
   void TryWrongNumCoefficients(int num) {
-    EXPECT_DEATH(
+    RTC_EXPECT_DEATH(
         [&] {
           auto config = MakeCngConfig();
           config.num_cng_coefficients = num;
@@ -454,9 +455,9 @@
 TEST_F(AudioEncoderCngDeathTest, WrongFrameSize) {
   CreateCng(MakeCngConfig());
   num_audio_samples_10ms_ *= 2;  // 20 ms frame.
-  EXPECT_DEATH(Encode(), "");
+  RTC_EXPECT_DEATH(Encode(), "");
   num_audio_samples_10ms_ = 0;  // Zero samples.
-  EXPECT_DEATH(Encode(), "");
+  RTC_EXPECT_DEATH(Encode(), "");
 }
 
 TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsA) {
@@ -474,16 +475,16 @@
 TEST_F(AudioEncoderCngDeathTest, NullSpeechEncoder) {
   auto config = MakeCngConfig();
   config.speech_encoder = nullptr;
-  EXPECT_DEATH(CreateCng(std::move(config)), "");
+  RTC_EXPECT_DEATH(CreateCng(std::move(config)), "");
 }
 
 TEST_F(AudioEncoderCngDeathTest, StereoEncoder) {
   EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(2));
-  EXPECT_DEATH(CreateCng(MakeCngConfig()), "Invalid configuration");
+  RTC_EXPECT_DEATH(CreateCng(MakeCngConfig()), "Invalid configuration");
 }
 
 TEST_F(AudioEncoderCngDeathTest, StereoConfig) {
-  EXPECT_DEATH(
+  RTC_EXPECT_DEATH(
       [&] {
         auto config = MakeCngConfig();
         config.num_channels = 2;
@@ -498,8 +499,8 @@
       .WillRepeatedly(Return(7U));
   for (int i = 0; i < 6; ++i)
     Encode();
-  EXPECT_DEATH(Encode(),
-               "Frame size cannot be larger than 60 ms when using VAD/CNG.");
+  RTC_EXPECT_DEATH(
+      Encode(), "Frame size cannot be larger than 60 ms when using VAD/CNG.");
 }
 
 #endif  // GTEST_HAS_DEATH_TEST
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
index 22e9a7f..648a88d 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
@@ -17,6 +17,7 @@
 #include "rtc_base/numerics/safe_conversions.h"
 #include "test/gtest.h"
 #include "test/mock_audio_encoder.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 using ::testing::_;
 using ::testing::InSequence;
@@ -285,17 +286,17 @@
 
 TEST_F(AudioEncoderCopyRedDeathTest, WrongFrameSize) {
   num_audio_samples_10ms *= 2;  // 20 ms frame.
-  EXPECT_DEATH(Encode(), "");
+  RTC_EXPECT_DEATH(Encode(), "");
   num_audio_samples_10ms = 0;  // Zero samples.
-  EXPECT_DEATH(Encode(), "");
+  RTC_EXPECT_DEATH(Encode(), "");
 }
 
 TEST_F(AudioEncoderCopyRedDeathTest, NullSpeechEncoder) {
   AudioEncoderCopyRed* red = NULL;
   AudioEncoderCopyRed::Config config;
   config.speech_encoder = NULL;
-  EXPECT_DEATH(red = new AudioEncoderCopyRed(std::move(config)),
-               "Speech encoder not provided.");
+  RTC_EXPECT_DEATH(red = new AudioEncoderCopyRed(std::move(config)),
+                   "Speech encoder not provided.");
   // The delete operation is needed to avoid leak reports from memcheck.
   delete red;
 }
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 9e6ee75..a0f6124 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -448,6 +448,7 @@
       "../../system_wrappers",
       "../../system_wrappers:cpu_features_api",
       "../../test:fileutils",
+      "../../test:rtc_expect_death",
       "../../test:test_support",
       "../audio_coding:neteq_input_audio_tools",
       "aec:aec_core",
diff --git a/modules/audio_processing/audio_buffer_unittest.cc b/modules/audio_processing/audio_buffer_unittest.cc
index 402e5c4..7cb51ca 100644
--- a/modules/audio_processing/audio_buffer_unittest.cc
+++ b/modules/audio_processing/audio_buffer_unittest.cc
@@ -11,7 +11,9 @@
 #include "modules/audio_processing/audio_buffer.h"
 
 #include <cmath>
+
 #include "test/gtest.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 namespace webrtc {
 
@@ -41,7 +43,7 @@
 TEST(AudioBufferTest, SetNumChannelsDeathTest) {
   AudioBuffer ab(kSampleRateHz, kMono, kSampleRateHz, kMono, kSampleRateHz,
                  kMono);
-  EXPECT_DEATH(ab.set_num_channels(kStereo), "num_channels");
+  RTC_EXPECT_DEATH(ab.set_num_channels(kStereo), "num_channels");
 }
 #endif
 
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index d626add..41e553c 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -1168,6 +1168,7 @@
       "buffer_unittest.cc",
       "byte_buffer_unittest.cc",
       "byte_order_unittest.cc",
+      "checks_unittest.cc",
       "copy_on_write_buffer_unittest.cc",
       "critical_section_unittest.cc",
       "event_tracer_unittest.cc",
diff --git a/rtc_base/checks.cc b/rtc_base/checks.cc
index 34a1b72..e5fc2ed 100644
--- a/rtc_base/checks.cc
+++ b/rtc_base/checks.cc
@@ -59,6 +59,7 @@
 namespace rtc {
 namespace webrtc_checks_impl {
 
+#if RTC_CHECK_MSG_ENABLED
 // Reads one argument from args, appends it to s and advances fmt.
 // Returns true iff an argument was sucessfully parsed.
 bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) {
@@ -162,6 +163,32 @@
 #endif
   abort();
 }
+#else  // RTC_CHECK_MSG_ENABLED
+RTC_NORETURN void FatalLog(const char* file, int line) {
+  std::string s;
+  AppendFormat(&s,
+               "\n\n"
+               "#\n"
+               "# Fatal error in: %s, line %d\n"
+               "# last system error: %u\n"
+               "# Check failed.\n"
+               "# ",
+               file, line, LAST_SYSTEM_ERROR);
+  const char* output = s.c_str();
+
+#if defined(WEBRTC_ANDROID)
+  __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output);
+#endif
+
+  fflush(stdout);
+  fprintf(stderr, "%s", output);
+  fflush(stderr);
+#if defined(WEBRTC_WIN)
+  DebugBreak();
+#endif
+  abort();
+}
+#endif  // RTC_CHECK_MSG_ENABLED
 
 }  // namespace webrtc_checks_impl
 }  // namespace rtc
@@ -170,7 +197,11 @@
 RTC_NORETURN void rtc_FatalMessage(const char* file,
                                    int line,
                                    const char* msg) {
+#if RTC_CHECK_MSG_ENABLED
   static constexpr rtc::webrtc_checks_impl::CheckArgType t[] = {
       rtc::webrtc_checks_impl::CheckArgType::kEnd};
-  FatalLog(file, line, msg, t);
+  rtc::webrtc_checks_impl::FatalLog(file, line, msg, t);
+#else
+  rtc::webrtc_checks_impl::FatalLog(file, line);
+#endif
 }
diff --git a/rtc_base/checks.h b/rtc_base/checks.h
index 17d32cb..8d361cf 100644
--- a/rtc_base/checks.h
+++ b/rtc_base/checks.h
@@ -37,6 +37,18 @@
 }  // extern "C"
 #endif
 
+#ifdef RTC_DISABLE_CHECK_MSG
+#define RTC_CHECK_MSG_ENABLED 0
+#else
+#define RTC_CHECK_MSG_ENABLED 1
+#endif
+
+#if RTC_CHECK_MSG_ENABLED
+#define RTC_CHECK_EVAL_MESSAGE(message) message
+#else
+#define RTC_CHECK_EVAL_MESSAGE(message) ""
+#endif
+
 #ifdef __cplusplus
 // C++ version.
 
@@ -109,11 +121,15 @@
   kCheckOp,
 };
 
+#if RTC_CHECK_MSG_ENABLED
 RTC_NORETURN RTC_EXPORT void FatalLog(const char* file,
                                       int line,
                                       const char* message,
                                       const CheckArgType* fmt,
                                       ...);
+#else
+RTC_NORETURN RTC_EXPORT void FatalLog(const char* file, int line);
+#endif
 
 // Wrapper for log arguments. Only ever make values of this type with the
 // MakeVal() functions.
@@ -214,6 +230,7 @@
     return LogStreamer<V>(MakeVal(arg), this);
   }
 
+#if RTC_CHECK_MSG_ENABLED
   template <typename... Us>
   RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
                                                  const int line,
@@ -232,6 +249,13 @@
                                          CheckArgType::kEnd};
     FatalLog(file, line, message, t, args.GetVal()...);
   }
+#else
+  template <typename... Us>
+  RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
+                                                 const int line) {
+    FatalLog(file, line);
+  }
+#endif
 };
 
 // Inductive case: We've already seen at least one << argument. The most recent
@@ -258,6 +282,7 @@
     return LogStreamer<V, T, Ts...>(MakeVal(arg), this);
   }
 
+#if RTC_CHECK_MSG_ENABLED
   template <typename... Us>
   RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
                                           const int line,
@@ -273,6 +298,13 @@
                                                  const Us&... args) const {
     prior_->CallCheckOp(file, line, message, arg_, args...);
   }
+#else
+  template <typename... Us>
+  RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
+                                          const int line) const {
+    prior_->Call(file, line);
+  }
+#endif
 
  private:
   // The most recent argument.
@@ -292,8 +324,12 @@
   template <typename... Ts>
   RTC_NORETURN RTC_FORCE_INLINE void operator&(
       const LogStreamer<Ts...>& streamer) {
+#if RTC_CHECK_MSG_ENABLED
     isCheckOp ? streamer.CallCheckOp(file_, line_, message_)
               : streamer.Call(file_, line_, message_);
+#else
+    streamer.Call(file_, line_);
+#endif
   }
 
  private:
@@ -301,6 +337,7 @@
   int line_;
   const char* message_;
 };
+
 }  // namespace webrtc_checks_impl
 
 // The actual stream used isn't important. We reference |ignored| in the code
@@ -326,19 +363,37 @@
 //
 // We make sure RTC_CHECK et al. always evaluates |condition|, as
 // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
+//
+// RTC_CHECK_OP is a helper macro for binary operators.
+// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
+#if RTC_CHECK_MSG_ENABLED
 #define RTC_CHECK(condition)                                       \
   while (!(condition))                                             \
   rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
                                                #condition) &       \
       rtc::webrtc_checks_impl::LogStreamer<>()
 
-// Helper macro for binary operators.
-// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
 #define RTC_CHECK_OP(name, op, val1, val2)                               \
   while (!rtc::Safe##name((val1), (val2)))                               \
   rtc::webrtc_checks_impl::FatalLogCall<true>(__FILE__, __LINE__,        \
                                               #val1 " " #op " " #val2) & \
       rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2)
+#else
+#define RTC_CHECK(condition)                                                   \
+  while (!(condition))                                                         \
+  true                                                                         \
+      ? rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, "") & \
+            rtc::webrtc_checks_impl::LogStreamer<>()                           \
+      : rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") &              \
+            rtc::webrtc_checks_impl::LogStreamer<>()
+
+#define RTC_CHECK_OP(name, op, val1, val2)                                     \
+  while (!rtc::Safe##name((val1), (val2)))                                     \
+  true ? rtc::webrtc_checks_impl::FatalLogCall<true>(__FILE__, __LINE__, "") & \
+             rtc::webrtc_checks_impl::LogStreamer<>()                          \
+       : rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") &             \
+             rtc::webrtc_checks_impl::LogStreamer<>()
+#endif
 
 #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
 #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
@@ -391,11 +446,12 @@
 // C version. Lacks many features compared to the C++ version, but usage
 // guidelines are the same.
 
-#define RTC_CHECK(condition)                                             \
-  do {                                                                   \
-    if (!(condition)) {                                                  \
-      rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \
-    }                                                                    \
+#define RTC_CHECK(condition)                                                 \
+  do {                                                                       \
+    if (!(condition)) {                                                      \
+      rtc_FatalMessage(__FILE__, __LINE__,                                   \
+                       RTC_CHECK_EVAL_MESSAGE("CHECK failed: " #condition)); \
+    }                                                                        \
   } while (0)
 
 #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
@@ -405,11 +461,12 @@
 #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
 #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
 
-#define RTC_DCHECK(condition)                                             \
-  do {                                                                    \
-    if (RTC_DCHECK_IS_ON && !(condition)) {                               \
-      rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \
-    }                                                                     \
+#define RTC_DCHECK(condition)                                                 \
+  do {                                                                        \
+    if (RTC_DCHECK_IS_ON && !(condition)) {                                   \
+      rtc_FatalMessage(__FILE__, __LINE__,                                    \
+                       RTC_CHECK_EVAL_MESSAGE("DCHECK failed: " #condition)); \
+    }                                                                         \
   } while (0)
 
 #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
diff --git a/rtc_base/checks_unittest.cc b/rtc_base/checks_unittest.cc
new file mode 100644
index 0000000..e6e094e
--- /dev/null
+++ b/rtc_base/checks_unittest.cc
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "rtc_base/checks.h"
+
+#include "test/gtest.h"
+
+TEST(ChecksTest, ExpressionNotEvaluatedWhenCheckPassing) {
+  int i = 0;
+  RTC_CHECK(true) << "i=" << ++i;
+  RTC_CHECK_EQ(i, 0) << "Previous check passed, but i was incremented!";
+}
+
+#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+TEST(ChecksTest, Checks) {
+#if RTC_CHECK_MSG_ENABLED
+  EXPECT_DEATH(FATAL() << "message",
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed: FATAL\\(\\)\n"
+               "# message");
+
+  int a = 1, b = 2;
+  EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u,
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed: a == b \\(1 vs. 2\\)\n"
+               "# 12");
+  RTC_CHECK_EQ(5, 5);
+
+  RTC_CHECK(true) << "Shouldn't crash" << 1;
+  EXPECT_DEATH(RTC_CHECK(false) << "Hi there!",
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed: false\n"
+               "# Hi there!");
+#else
+  EXPECT_DEATH(FATAL() << "message",
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed.\n"
+               "# ");
+
+  int a = 1, b = 2;
+  EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u,
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed.\n"
+               "# ");
+  RTC_CHECK_EQ(5, 5);
+
+  RTC_CHECK(true) << "Shouldn't crash" << 1;
+  EXPECT_DEATH(RTC_CHECK(false) << "Hi there!",
+               "\n\n#\n"
+               "# Fatal error in: \\S+, line \\w+\n"
+               "# last system error: \\w+\n"
+               "# Check failed.\n"
+               "# ");
+#endif  // RTC_CHECK_MSG_ENABLED
+}
+#endif  // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
diff --git a/rtc_base/logging_unittest.cc b/rtc_base/logging_unittest.cc
index f17291f..969ffeb 100644
--- a/rtc_base/logging_unittest.cc
+++ b/rtc_base/logging_unittest.cc
@@ -200,34 +200,6 @@
   EXPECT_EQ(sev, LogMessage::GetLogToStream(nullptr));
 }
 
-#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
-TEST(LogTest, Checks) {
-  EXPECT_DEATH(FATAL() << "message",
-               "\n\n#\n"
-               "# Fatal error in: \\S+, line \\w+\n"
-               "# last system error: \\w+\n"
-               "# Check failed: FATAL\\(\\)\n"
-               "# message");
-
-  int a = 1, b = 2;
-  EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u,
-               "\n\n#\n"
-               "# Fatal error in: \\S+, line \\w+\n"
-               "# last system error: \\w+\n"
-               "# Check failed: a == b \\(1 vs. 2\\)\n"
-               "# 12");
-  RTC_CHECK_EQ(5, 5);
-
-  RTC_CHECK(true) << "Shouldn't crash" << 1;
-  EXPECT_DEATH(RTC_CHECK(false) << "Hi there!",
-               "\n\n#\n"
-               "# Fatal error in: \\S+, line \\w+\n"
-               "# last system error: \\w+\n"
-               "# Check failed: false\n"
-               "# Hi there!");
-}
-#endif
-
 // Test using multiple log streams. The INFO stream should get the INFO message,
 // the VERBOSE stream should get the INFO and the VERBOSE.
 // We should restore the correct global state at the end.
diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn
index f32cafe..2f30a16 100644
--- a/system_wrappers/BUILD.gn
+++ b/system_wrappers/BUILD.gn
@@ -173,6 +173,7 @@
       ":system_wrappers",
       "../rtc_base:checks",
       "../rtc_base:rtc_base_approved",
+      "../test:rtc_expect_death",
       "../test:test_main",
       "../test:test_support",
       "//testing/gtest",
diff --git a/system_wrappers/source/field_trial_unittest.cc b/system_wrappers/source/field_trial_unittest.cc
index f681948..67b841d 100644
--- a/system_wrappers/source/field_trial_unittest.cc
+++ b/system_wrappers/source/field_trial_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "rtc_base/checks.h"
 #include "test/gtest.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 namespace webrtc {
 namespace field_trial {
@@ -28,23 +29,24 @@
 
 TEST(FieldTrialValidationTest, RejectsBadInputs) {
   // Bad delimiters
-  EXPECT_DEATH(InitFieldTrialsFromString("Audio/EnabledVideo/Disabled/"),
-               "Invalid field trials string:");
-  EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled//Video/Disabled/"),
-               "Invalid field trials string:");
-  EXPECT_DEATH(InitFieldTrialsFromString("/Audio/Enabled/Video/Disabled/"),
-               "Invalid field trials string:");
-  EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Video/Disabled"),
-               "Invalid field trials string:");
-  EXPECT_DEATH(
+  RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/EnabledVideo/Disabled/"),
+                   "Invalid field trials string:");
+  RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled//Video/Disabled/"),
+                   "Invalid field trials string:");
+  RTC_EXPECT_DEATH(InitFieldTrialsFromString("/Audio/Enabled/Video/Disabled/"),
+                   "Invalid field trials string:");
+  RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Video/Disabled"),
+                   "Invalid field trials string:");
+  RTC_EXPECT_DEATH(
       InitFieldTrialsFromString("Audio/Enabled/Video/Disabled/garbage"),
       "Invalid field trials string:");
 
   // Duplicate trials with different values is not fine
-  EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Audio/Disabled/"),
-               "Invalid field trials string:");
-  EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/B/C/Audio/Disabled/"),
-               "Invalid field trials string:");
+  RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Audio/Disabled/"),
+                   "Invalid field trials string:");
+  RTC_EXPECT_DEATH(
+      InitFieldTrialsFromString("Audio/Enabled/B/C/Audio/Disabled/"),
+      "Invalid field trials string:");
 }
 #endif  // GTEST_HAS_DEATH_TEST && RTC_DCHECK_IS_ON && !defined(WEBRTC_ANDROID)
         // && !defined(WEBRTC_EXCLUDE_FIELD_TRIAL_DEFAULT)
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 0c30e7f..1a1147f 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -385,6 +385,7 @@
       ":fileutils",
       ":fileutils_unittests",
       ":perf_test",
+      ":rtc_expect_death",
       ":rtp_test_utils",
       ":test_main",
       ":test_support",
@@ -714,6 +715,16 @@
   ]
 }
 
+rtc_library("rtc_expect_death") {
+  testonly = true
+  sources = [
+    "testsupport/rtc_expect_death.h",
+  ]
+  deps = [
+    ":test_support",
+  ]
+}
+
 rtc_library("test_common") {
   testonly = true
   sources = [
diff --git a/test/testsupport/perf_test_unittest.cc b/test/testsupport/perf_test_unittest.cc
index ecc4258..8202471 100644
--- a/test/testsupport/perf_test_unittest.cc
+++ b/test/testsupport/perf_test_unittest.cc
@@ -15,6 +15,7 @@
 #include <string>
 
 #include "test/gtest.h"
+#include "test/testsupport/rtc_expect_death.h"
 
 namespace {
 
@@ -113,16 +114,18 @@
   const double kNan = std::numeric_limits<double>::quiet_NaN();
   const double kInf = std::numeric_limits<double>::infinity();
 
-  EXPECT_DEATH(PrintResult("a", "b", "c", kNan, "d", false), "finit");
-  EXPECT_DEATH(PrintResult("a", "b", "c", kInf, "d", false), "finit");
+  RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kNan, "d", false), "finit");
+  RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kInf, "d", false), "finit");
 
-  EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", kNan, 1, "d", false), "");
-  EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", 1, kInf, "d", false), "");
+  RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", kNan, 1, "d", false),
+                   "");
+  RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", 1, kInf, "d", false),
+                   "");
 
   const double kNanList[] = {kNan, kNan};
-  EXPECT_DEATH(PrintResultList("a", "b", "c", kNanList, "d", false), "");
+  RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kNanList, "d", false), "");
   const double kInfList[] = {0, kInf};
-  EXPECT_DEATH(PrintResultList("a", "b", "c", kInfList, "d", false), "");
+  RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kInfList, "d", false), "");
 }
 #endif
 
diff --git a/test/testsupport/rtc_expect_death.h b/test/testsupport/rtc_expect_death.h
new file mode 100644
index 0000000..5941e12
--- /dev/null
+++ b/test/testsupport/rtc_expect_death.h
@@ -0,0 +1,23 @@
+/*
+ *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_
+#define TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_
+
+#include "test/gtest.h"
+
+#if RTC_CHECK_MSG_ENABLED
+#define RTC_EXPECT_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
+#else
+// If RTC_CHECKs messages are disabled we can't validate failure message
+#define RTC_EXPECT_DEATH(statement, regex) EXPECT_DEATH(statement, "")
+#endif
+
+#endif  // TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_
diff --git a/webrtc.gni b/webrtc.gni
index 2aefe25..56a1b0d 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -248,6 +248,10 @@
 
   # Set this to true to disable trace events.
   rtc_disable_trace_events = false
+
+  # Set this to true to disable detailed error message and logging for
+  # RTC_CHECKs.
+  rtc_disable_check_msg = false
 }
 
 # Make it possible to provide custom locations for some libraries (move these