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 |