| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2006 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef WEBRTC_BASE_CHECKS_H_ | 11 #ifndef WEBRTC_BASE_CHECKS_H_ |
| 12 #define WEBRTC_BASE_CHECKS_H_ | 12 #define WEBRTC_BASE_CHECKS_H_ |
| 13 | 13 |
| 14 #include <sstream> | 14 #include <sstream> |
| 15 #include <string> | 15 #include <string> |
| 16 | 16 |
| 17 #ifdef WEBRTC_CHROMIUM_BUILD | 17 #ifdef WEBRTC_CHROMIUM_BUILD |
| 18 // Include logging.h in a Chromium build to enable the overrides mechanism for | 18 // Include logging.h in a Chromium build to enable the overrides mechanism for |
| 19 // using Chromium's macros. Otherwise, don't depend on logging.h. | 19 // using Chromium's macros. Otherwise, don't depend on logging.h. |
| 20 // TODO(ajm): Ideally, checks.h would be combined with logging.h, but | 20 // TODO(ajm): Ideally, checks.h would be combined with logging.h, but |
| 21 // consolidation with system_wrappers/logging.h should happen first. | 21 // consolidation with system_wrappers/logging.h should happen first. |
| 22 #include "webrtc/base/logging.h" | 22 #include "webrtc/base/logging.h" |
| 23 #endif | 23 #endif |
| 24 #include "webrtc/typedefs.h" | 24 #include "webrtc/typedefs.h" |
| 25 | 25 |
| 26 // The macros here print a message to stderr and abort under various | 26 // The macros here print a message to stderr and abort under various |
| 27 // conditions. All will accept additional stream messages. For example: | 27 // conditions. All will accept additional stream messages. For example: |
| 28 // DCHECK_EQ(foo, bar) << "I'm printed when foo != bar."; | 28 // RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar."; |
| 29 // | 29 // |
| 30 // - CHECK(x) is an assertion that x is always true, and that if it isn't, it's | 30 // - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't, |
| 31 // better to terminate the process than to continue. During development, the | 31 // it's better to terminate the process than to continue. During development, |
| 32 // reason that it's better to terminate might simply be that the error | 32 // the reason that it's better to terminate might simply be that the error |
| 33 // handling code isn't in place yet; in production, the reason might be that | 33 // handling code isn't in place yet; in production, the reason might be that |
| 34 // the author of the code truly believes that x will always be true, but that | 34 // the author of the code truly believes that x will always be true, but that |
| 35 // she recognizes that if she is wrong, abrupt and unpleasant process | 35 // she recognizes that if she is wrong, abrupt and unpleasant process |
| 36 // termination is still better than carrying on with the assumption violated. | 36 // termination is still better than carrying on with the assumption violated. |
| 37 // | 37 // |
| 38 // CHECK always evaluates its argument, so it's OK for x to have side | 38 // RTC_CHECK always evaluates its argument, so it's OK for x to have side |
| 39 // effects. | 39 // effects. |
| 40 // | 40 // |
| 41 // - DCHECK(x) is the same as CHECK(x)---an assertion that x is always | 41 // - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always |
| 42 // true---except that x will only be evaluated in debug builds; in production | 42 // true---except that x will only be evaluated in debug builds; in production |
| 43 // builds, x is simply assumed to be true. This is useful if evaluating x is | 43 // builds, x is simply assumed to be true. This is useful if evaluating x is |
| 44 // expensive and the expected cost of failing to detect the violated | 44 // expensive and the expected cost of failing to detect the violated |
| 45 // assumption is acceptable. You should not handle cases where a production | 45 // assumption is acceptable. You should not handle cases where a production |
| 46 // build fails to spot a violated condition, even those that would result in | 46 // build fails to spot a violated condition, even those that would result in |
| 47 // crashes. If the code needs to cope with the error, make it cope, but don't | 47 // crashes. If the code needs to cope with the error, make it cope, but don't |
| 48 // call DCHECK; if the condition really can't occur, but you'd sleep better | 48 // call RTC_DCHECK; if the condition really can't occur, but you'd sleep |
| 49 // at night knowing that the process will suicide instead of carrying on in | 49 // better at night knowing that the process will suicide instead of carrying |
| 50 // case you were wrong, use CHECK instead of DCHECK. | 50 // on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK. |
| 51 // | 51 // |
| 52 // DCHECK only evaluates its argument in debug builds, so if x has visible | 52 // RTC_DCHECK only evaluates its argument in debug builds, so if x has visible |
| 53 // side effects, you need to write e.g. | 53 // side effects, you need to write e.g. |
| 54 // bool w = x; DCHECK(w); | 54 // bool w = x; RTC_DCHECK(w); |
| 55 // | 55 // |
| 56 // - CHECK_EQ, _NE, _GT, ..., and DCHECK_EQ, _NE, _GT, ... are specialized | 56 // - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are |
| 57 // variants of CHECK and DCHECK that print prettier messages if the condition | 57 // specialized variants of RTC_CHECK and RTC_DCHECK that print prettier |
| 58 // doesn't hold. Prefer them to raw CHECK and DCHECK. | 58 // messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and |
| 59 // RTC_DCHECK. |
| 59 // | 60 // |
| 60 // - FATAL() aborts unconditionally. | 61 // - FATAL() aborts unconditionally. |
| 61 | 62 |
| 62 namespace rtc { | 63 namespace rtc { |
| 63 | 64 |
| 64 // The use of overrides/webrtc/base/logging.h in a Chromium build results in | |
| 65 // redefined macro errors. Fortunately, Chromium's macros can be used as drop-in | |
| 66 // replacements for the standalone versions. | |
| 67 #ifndef WEBRTC_CHROMIUM_BUILD | |
| 68 | |
| 69 // Helper macro which avoids evaluating the arguments to a stream if | 65 // Helper macro which avoids evaluating the arguments to a stream if |
| 70 // the condition doesn't hold. | 66 // the condition doesn't hold. |
| 71 #define LAZY_STREAM(stream, condition) \ | 67 #define RTC_LAZY_STREAM(stream, condition) \ |
| 72 !(condition) ? static_cast<void>(0) : rtc::FatalMessageVoidify() & (stream) | 68 !(condition) ? static_cast<void>(0) : rtc::FatalMessageVoidify() & (stream) |
| 73 | 69 |
| 74 // The actual stream used isn't important. We reference condition in the code | 70 // The actual stream used isn't important. We reference condition in the code |
| 75 // but don't evaluate it; this is to avoid "unused variable" warnings (we do so | 71 // but don't evaluate it; this is to avoid "unused variable" warnings (we do so |
| 76 // in a particularly convoluted way with an extra ?: because that appears to be | 72 // in a particularly convoluted way with an extra ?: because that appears to be |
| 77 // the simplest construct that keeps Visual Studio from complaining about | 73 // the simplest construct that keeps Visual Studio from complaining about |
| 78 // condition being unused). | 74 // condition being unused). |
| 79 #define EAT_STREAM_PARAMETERS(condition) \ | 75 #define RTC_EAT_STREAM_PARAMETERS(condition) \ |
| 80 (true ? true : !(condition)) \ | 76 (true ? true : !(condition)) \ |
| 81 ? static_cast<void>(0) \ | 77 ? static_cast<void>(0) \ |
| 82 : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream() | 78 : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream() |
| 83 | 79 |
| 84 // CHECK dies with a fatal error if condition is not true. It is *not* | 80 // RTC_CHECK dies with a fatal error if condition is not true. It is *not* |
| 85 // controlled by NDEBUG, so the check will be executed regardless of | 81 // controlled by NDEBUG, so the check will be executed regardless of |
| 86 // compilation mode. | 82 // compilation mode. |
| 87 // | 83 // |
| 88 // We make sure CHECK et al. always evaluates their arguments, as | 84 // We make sure RTC_CHECK et al. always evaluates their arguments, as |
| 89 // doing CHECK(FunctionWithSideEffect()) is a common idiom. | 85 // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom. |
| 90 #define CHECK(condition) \ | 86 #define RTC_CHECK(condition) \ |
| 91 LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), !(condition)) \ | 87 RTC_LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), \ |
| 92 << "Check failed: " #condition << std::endl << "# " | 88 !(condition)) \ |
| 89 << "Check failed: " #condition << std::endl << "# " |
| 93 | 90 |
| 94 // Helper macro for binary operators. | 91 // Helper macro for binary operators. |
| 95 // Don't use this macro directly in your code, use CHECK_EQ et al below. | 92 // Don't use this macro directly in your code, use RTC_CHECK_EQ et al below. |
| 96 // | 93 // |
| 97 // TODO(akalin): Rewrite this so that constructs like if (...) | 94 // TODO(akalin): Rewrite this so that constructs like if (...) |
| 98 // CHECK_EQ(...) else { ... } work properly. | 95 // RTC_CHECK_EQ(...) else { ... } work properly. |
| 99 #define CHECK_OP(name, op, val1, val2) \ | 96 #define RTC_CHECK_OP(name, op, val1, val2) \ |
| 100 if (std::string* _result = \ | 97 if (std::string* _result = \ |
| 101 rtc::Check##name##Impl((val1), (val2), \ | 98 rtc::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ |
| 102 #val1 " " #op " " #val2)) \ | |
| 103 rtc::FatalMessage(__FILE__, __LINE__, _result).stream() | 99 rtc::FatalMessage(__FILE__, __LINE__, _result).stream() |
| 104 | 100 |
| 105 // Build the error message string. This is separate from the "Impl" | 101 // Build the error message string. This is separate from the "Impl" |
| 106 // function template because it is not performance critical and so can | 102 // function template because it is not performance critical and so can |
| 107 // be out of line, while the "Impl" code should be inline. Caller | 103 // be out of line, while the "Impl" code should be inline. Caller |
| 108 // takes ownership of the returned string. | 104 // takes ownership of the returned string. |
| 109 template<class t1, class t2> | 105 template<class t1, class t2> |
| 110 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { | 106 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { |
| 111 std::ostringstream ss; | 107 std::ostringstream ss; |
| 112 ss << names << " (" << v1 << " vs. " << v2 << ")"; | 108 ss << names << " (" << v1 << " vs. " << v2 << ")"; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 127 std::string* MakeCheckOpString<unsigned long, unsigned int>( | 123 std::string* MakeCheckOpString<unsigned long, unsigned int>( |
| 128 const unsigned long&, const unsigned int&, const char* names); | 124 const unsigned long&, const unsigned int&, const char* names); |
| 129 extern template | 125 extern template |
| 130 std::string* MakeCheckOpString<unsigned int, unsigned long>( | 126 std::string* MakeCheckOpString<unsigned int, unsigned long>( |
| 131 const unsigned int&, const unsigned long&, const char* names); | 127 const unsigned int&, const unsigned long&, const char* names); |
| 132 extern template | 128 extern template |
| 133 std::string* MakeCheckOpString<std::string, std::string>( | 129 std::string* MakeCheckOpString<std::string, std::string>( |
| 134 const std::string&, const std::string&, const char* name); | 130 const std::string&, const std::string&, const char* name); |
| 135 #endif | 131 #endif |
| 136 | 132 |
| 137 // Helper functions for CHECK_OP macro. | 133 // Helper functions for RTC_CHECK_OP macro. |
| 138 // The (int, int) specialization works around the issue that the compiler | 134 // The (int, int) specialization works around the issue that the compiler |
| 139 // will not instantiate the template version of the function on values of | 135 // will not instantiate the template version of the function on values of |
| 140 // unnamed enum type - see comment below. | 136 // unnamed enum type - see comment below. |
| 141 #define DEFINE_CHECK_OP_IMPL(name, op) \ | 137 #define DEFINE_RTC_CHECK_OP_IMPL(name, op) \ |
| 142 template <class t1, class t2> \ | 138 template <class t1, class t2> \ |
| 143 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ | 139 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ |
| 144 const char* names) { \ | 140 const char* names) { \ |
| 145 if (v1 op v2) return NULL; \ | 141 if (v1 op v2) \ |
| 146 else return rtc::MakeCheckOpString(v1, v2, names); \ | 142 return NULL; \ |
| 147 } \ | 143 else \ |
| 144 return rtc::MakeCheckOpString(v1, v2, names); \ |
| 145 } \ |
| 148 inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ | 146 inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ |
| 149 if (v1 op v2) return NULL; \ | 147 if (v1 op v2) \ |
| 150 else return rtc::MakeCheckOpString(v1, v2, names); \ | 148 return NULL; \ |
| 149 else \ |
| 150 return rtc::MakeCheckOpString(v1, v2, names); \ |
| 151 } | 151 } |
| 152 DEFINE_CHECK_OP_IMPL(EQ, ==) | 152 DEFINE_RTC_CHECK_OP_IMPL(EQ, ==) |
| 153 DEFINE_CHECK_OP_IMPL(NE, !=) | 153 DEFINE_RTC_CHECK_OP_IMPL(NE, !=) |
| 154 DEFINE_CHECK_OP_IMPL(LE, <=) | 154 DEFINE_RTC_CHECK_OP_IMPL(LE, <=) |
| 155 DEFINE_CHECK_OP_IMPL(LT, < ) | 155 DEFINE_RTC_CHECK_OP_IMPL(LT, < ) |
| 156 DEFINE_CHECK_OP_IMPL(GE, >=) | 156 DEFINE_RTC_CHECK_OP_IMPL(GE, >=) |
| 157 DEFINE_CHECK_OP_IMPL(GT, > ) | 157 DEFINE_RTC_CHECK_OP_IMPL(GT, > ) |
| 158 #undef DEFINE_CHECK_OP_IMPL | 158 #undef DEFINE_RTC_CHECK_OP_IMPL |
| 159 | 159 |
| 160 #define CHECK_EQ(val1, val2) CHECK_OP(EQ, ==, val1, val2) | 160 #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(EQ, ==, val1, val2) |
| 161 #define CHECK_NE(val1, val2) CHECK_OP(NE, !=, val1, val2) | 161 #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(NE, !=, val1, val2) |
| 162 #define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2) | 162 #define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(LE, <=, val1, val2) |
| 163 #define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2) | 163 #define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(LT, < , val1, val2) |
| 164 #define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2) | 164 #define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(GE, >=, val1, val2) |
| 165 #define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2) | 165 #define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(GT, > , val1, val2) |
| 166 | 166 |
| 167 // The DCHECK macro is equivalent to CHECK except that it only generates code | 167 // The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates |
| 168 // in debug builds. It does reference the condition parameter in all cases, | 168 // code in debug builds. It does reference the condition parameter in all cases, |
| 169 // though, so callers won't risk getting warnings about unused variables. | 169 // though, so callers won't risk getting warnings about unused variables. |
| 170 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) | 170 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) |
| 171 #define DCHECK(condition) CHECK(condition) | 171 #define RTC_DCHECK(condition) RTC_CHECK(condition) |
| 172 #define DCHECK_EQ(v1, v2) CHECK_EQ(v1, v2) | 172 #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2) |
| 173 #define DCHECK_NE(v1, v2) CHECK_NE(v1, v2) | 173 #define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2) |
| 174 #define DCHECK_LE(v1, v2) CHECK_LE(v1, v2) | 174 #define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2) |
| 175 #define DCHECK_LT(v1, v2) CHECK_LT(v1, v2) | 175 #define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2) |
| 176 #define DCHECK_GE(v1, v2) CHECK_GE(v1, v2) | 176 #define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2) |
| 177 #define DCHECK_GT(v1, v2) CHECK_GT(v1, v2) | 177 #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2) |
| 178 #else | 178 #else |
| 179 #define DCHECK(condition) EAT_STREAM_PARAMETERS(condition) | 179 #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition) |
| 180 #define DCHECK_EQ(v1, v2) EAT_STREAM_PARAMETERS((v1) == (v2)) | 180 #define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) == (v2)) |
| 181 #define DCHECK_NE(v1, v2) EAT_STREAM_PARAMETERS((v1) != (v2)) | 181 #define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) != (v2)) |
| 182 #define DCHECK_LE(v1, v2) EAT_STREAM_PARAMETERS((v1) <= (v2)) | 182 #define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) <= (v2)) |
| 183 #define DCHECK_LT(v1, v2) EAT_STREAM_PARAMETERS((v1) < (v2)) | 183 #define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) < (v2)) |
| 184 #define DCHECK_GE(v1, v2) EAT_STREAM_PARAMETERS((v1) >= (v2)) | 184 #define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) >= (v2)) |
| 185 #define DCHECK_GT(v1, v2) EAT_STREAM_PARAMETERS((v1) > (v2)) | 185 #define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) > (v2)) |
| 186 #endif | 186 #endif |
| 187 | 187 |
| 188 // This is identical to LogMessageVoidify but in name. | 188 // This is identical to LogMessageVoidify but in name. |
| 189 class FatalMessageVoidify { | 189 class FatalMessageVoidify { |
| 190 public: | 190 public: |
| 191 FatalMessageVoidify() { } | 191 FatalMessageVoidify() { } |
| 192 // This has to be an operator with a precedence lower than << but | 192 // This has to be an operator with a precedence lower than << but |
| 193 // higher than ?: | 193 // higher than ?: |
| 194 void operator&(std::ostream&) { } | 194 void operator&(std::ostream&) { } |
| 195 }; | 195 }; |
| 196 | 196 |
| 197 #endif // WEBRTC_CHROMIUM_BUILD | |
| 198 | |
| 199 #define RTC_UNREACHABLE_CODE_HIT false | 197 #define RTC_UNREACHABLE_CODE_HIT false |
| 200 #define RTC_NOTREACHED() DCHECK(RTC_UNREACHABLE_CODE_HIT) | 198 #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT) |
| 201 | 199 |
| 202 #define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream() | 200 #define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream() |
| 203 // TODO(ajm): Consider adding NOTIMPLEMENTED and NOTREACHED macros when | 201 // TODO(ajm): Consider adding RTC_NOTIMPLEMENTED macro when |
| 204 // base/logging.h and system_wrappers/logging.h are consolidated such that we | 202 // base/logging.h and system_wrappers/logging.h are consolidated such that we |
| 205 // can match the Chromium behavior. | 203 // can match the Chromium behavior. |
| 206 | 204 |
| 207 // Like a stripped-down LogMessage from logging.h, except that it aborts. | 205 // Like a stripped-down LogMessage from logging.h, except that it aborts. |
| 208 class FatalMessage { | 206 class FatalMessage { |
| 209 public: | 207 public: |
| 210 FatalMessage(const char* file, int line); | 208 FatalMessage(const char* file, int line); |
| 211 // Used for CHECK_EQ(), etc. Takes ownership of the given string. | 209 // Used for RTC_CHECK_EQ(), etc. Takes ownership of the given string. |
| 212 FatalMessage(const char* file, int line, std::string* result); | 210 FatalMessage(const char* file, int line, std::string* result); |
| 213 NO_RETURN ~FatalMessage(); | 211 NO_RETURN ~FatalMessage(); |
| 214 | 212 |
| 215 std::ostream& stream() { return stream_; } | 213 std::ostream& stream() { return stream_; } |
| 216 | 214 |
| 217 private: | 215 private: |
| 218 void Init(const char* file, int line); | 216 void Init(const char* file, int line); |
| 219 | 217 |
| 220 std::ostringstream stream_; | 218 std::ostringstream stream_; |
| 221 }; | 219 }; |
| 222 | 220 |
| 223 // Performs the integer division a/b and returns the result. CHECKs that the | 221 // Performs the integer division a/b and returns the result. CHECKs that the |
| 224 // remainder is zero. | 222 // remainder is zero. |
| 225 template <typename T> | 223 template <typename T> |
| 226 inline T CheckedDivExact(T a, T b) { | 224 inline T CheckedDivExact(T a, T b) { |
| 227 CHECK_EQ(a % b, static_cast<T>(0)); | 225 RTC_CHECK_EQ(a % b, static_cast<T>(0)); |
| 228 return a / b; | 226 return a / b; |
| 229 } | 227 } |
| 230 | 228 |
| 231 } // namespace rtc | 229 } // namespace rtc |
| 232 | 230 |
| 233 #endif // WEBRTC_BASE_CHECKS_H_ | 231 #endif // WEBRTC_BASE_CHECKS_H_ |
| OLD | NEW |