check.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_CHECK_H_
  5. #define BASE_CHECK_H_
  6. #include <iosfwd>
  7. #include "base/base_export.h"
  8. #include "base/compiler_specific.h"
  9. #include "base/immediate_crash.h"
  10. // This header defines the CHECK, DCHECK, and DPCHECK macros.
  11. //
  12. // CHECK dies with a fatal error if its condition is not true. It is not
  13. // controlled by NDEBUG, so the check will be executed regardless of compilation
  14. // mode.
  15. //
  16. // DCHECK, the "debug mode" check, is enabled depending on NDEBUG and
  17. // DCHECK_ALWAYS_ON, and its severity depends on DCHECK_IS_CONFIGURABLE.
  18. //
  19. // (D)PCHECK is like (D)CHECK, but includes the system error code (c.f.
  20. // perror(3)).
  21. //
  22. // Additional information can be streamed to these macros and will be included
  23. // in the log output if the condition doesn't hold (you may need to include
  24. // <ostream>):
  25. //
  26. // CHECK(condition) << "Additional info.";
  27. //
  28. // The condition is evaluated exactly once. Even in build modes where e.g.
  29. // DCHECK is disabled, the condition and any stream arguments are still
  30. // referenced to avoid warnings about unused variables and functions.
  31. //
  32. // For the (D)CHECK_EQ, etc. macros, see base/check_op.h. However, that header
  33. // is *significantly* larger than check.h, so try to avoid including it in
  34. // header files.
  35. namespace logging {
  36. // Class used to explicitly ignore an ostream, and optionally a boolean value.
  37. class VoidifyStream {
  38. public:
  39. VoidifyStream() = default;
  40. explicit VoidifyStream(bool ignored) {}
  41. // This operator has lower precedence than << but higher than ?:
  42. void operator&(std::ostream&) {}
  43. };
  44. // Helper macro which avoids evaluating the arguents to a stream if the
  45. // condition is false.
  46. #define LAZY_CHECK_STREAM(stream, condition) \
  47. !(condition) ? (void)0 : ::logging::VoidifyStream() & (stream)
  48. // Macro which uses but does not evaluate expr and any stream parameters.
  49. #define EAT_CHECK_STREAM_PARAMS(expr) \
  50. true ? (void)0 \
  51. : ::logging::VoidifyStream(expr) & (*::logging::g_swallow_stream)
  52. BASE_EXPORT extern std::ostream* g_swallow_stream;
  53. class CheckOpResult;
  54. class LogMessage;
  55. // Class used for raising a check error upon destruction.
  56. class BASE_EXPORT CheckError {
  57. public:
  58. static CheckError Check(const char* file, int line, const char* condition);
  59. static CheckError CheckOp(const char* file, int line, CheckOpResult* result);
  60. static CheckError DCheck(const char* file, int line, const char* condition);
  61. static CheckError DCheckOp(const char* file, int line, CheckOpResult* result);
  62. static CheckError PCheck(const char* file, int line, const char* condition);
  63. static CheckError PCheck(const char* file, int line);
  64. static CheckError DPCheck(const char* file, int line, const char* condition);
  65. static CheckError NotImplemented(const char* file,
  66. int line,
  67. const char* function);
  68. // Stream for adding optional details to the error message.
  69. std::ostream& stream();
  70. ~CheckError();
  71. CheckError(const CheckError& other) = delete;
  72. CheckError& operator=(const CheckError& other) = delete;
  73. CheckError(CheckError&& other) = default;
  74. CheckError& operator=(CheckError&& other) = default;
  75. private:
  76. explicit CheckError(LogMessage* log_message);
  77. LogMessage* log_message_;
  78. };
  79. #if defined(OFFICIAL_BUILD) && defined(NDEBUG)
  80. // Discard log strings to reduce code bloat.
  81. //
  82. // This is not calling BreakDebugger since this is called frequently, and
  83. // calling an out-of-line function instead of a noreturn inline macro prevents
  84. // compiler optimizations.
  85. #define CHECK(condition) \
  86. UNLIKELY(!(condition)) ? IMMEDIATE_CRASH() : EAT_CHECK_STREAM_PARAMS()
  87. #define PCHECK(condition) \
  88. LAZY_CHECK_STREAM( \
  89. ::logging::CheckError::PCheck(__FILE__, __LINE__).stream(), \
  90. UNLIKELY(!(condition)))
  91. #else
  92. #define CHECK(condition) \
  93. LAZY_CHECK_STREAM( \
  94. ::logging::CheckError::Check(__FILE__, __LINE__, #condition).stream(), \
  95. !ANALYZER_ASSUME_TRUE(condition))
  96. #define PCHECK(condition) \
  97. LAZY_CHECK_STREAM( \
  98. ::logging::CheckError::PCheck(__FILE__, __LINE__, #condition).stream(), \
  99. !ANALYZER_ASSUME_TRUE(condition))
  100. #endif
  101. #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
  102. #define DCHECK_IS_ON() false
  103. #else
  104. #define DCHECK_IS_ON() true
  105. #endif
  106. #if DCHECK_IS_ON()
  107. #define DCHECK(condition) \
  108. LAZY_CHECK_STREAM( \
  109. ::logging::CheckError::DCheck(__FILE__, __LINE__, #condition).stream(), \
  110. !ANALYZER_ASSUME_TRUE(condition))
  111. #define DPCHECK(condition) \
  112. LAZY_CHECK_STREAM( \
  113. ::logging::CheckError::DPCheck(__FILE__, __LINE__, #condition).stream(), \
  114. !ANALYZER_ASSUME_TRUE(condition))
  115. #else
  116. #define DCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
  117. #define DPCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
  118. #endif
  119. // Async signal safe checking mechanism.
  120. BASE_EXPORT void RawCheck(const char* message);
  121. #define RAW_CHECK(condition) \
  122. do { \
  123. if (!(condition)) \
  124. ::logging::RawCheck("Check failed: " #condition "\n"); \
  125. } while (0)
  126. } // namespace logging
  127. #endif // BASE_CHECK_H_