check.h 5.7 KB

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