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 "webrtc/typedefs.h" | |
15 | 14 |
16 // If you for some reson need to know if DCHECKs are on, test the value of | 15 // This header is deprecated and is just left here temporarily during |
17 // RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be | 16 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
18 // defined, to either a true or a false value.) | 17 #include "webrtc/rtc_base/checks.h" |
19 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) | |
20 #define RTC_DCHECK_IS_ON 1 | |
21 #else | |
22 #define RTC_DCHECK_IS_ON 0 | |
23 #endif | |
24 | |
25 #ifdef __cplusplus | |
26 extern "C" { | |
27 #endif | |
28 NO_RETURN void rtc_FatalMessage(const char* file, int line, const char* msg); | |
29 #ifdef __cplusplus | |
30 } // extern "C" | |
31 #endif | |
32 | |
33 #ifdef __cplusplus | |
34 // C++ version. | |
35 | |
36 #include <sstream> | |
37 #include <string> | |
38 | |
39 #include "webrtc/base/safe_compare.h" | |
40 | |
41 // The macros here print a message to stderr and abort under various | |
42 // conditions. All will accept additional stream messages. For example: | |
43 // RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar."; | |
44 // | |
45 // - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't, | |
46 // it's better to terminate the process than to continue. During development, | |
47 // the reason that it's better to terminate might simply be that the error | |
48 // handling code isn't in place yet; in production, the reason might be that | |
49 // the author of the code truly believes that x will always be true, but that | |
50 // she recognizes that if she is wrong, abrupt and unpleasant process | |
51 // termination is still better than carrying on with the assumption violated. | |
52 // | |
53 // RTC_CHECK always evaluates its argument, so it's OK for x to have side | |
54 // effects. | |
55 // | |
56 // - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always | |
57 // true---except that x will only be evaluated in debug builds; in production | |
58 // builds, x is simply assumed to be true. This is useful if evaluating x is | |
59 // expensive and the expected cost of failing to detect the violated | |
60 // assumption is acceptable. You should not handle cases where a production | |
61 // build fails to spot a violated condition, even those that would result in | |
62 // crashes. If the code needs to cope with the error, make it cope, but don't | |
63 // call RTC_DCHECK; if the condition really can't occur, but you'd sleep | |
64 // better at night knowing that the process will suicide instead of carrying | |
65 // on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK. | |
66 // | |
67 // RTC_DCHECK only evaluates its argument in debug builds, so if x has visible | |
68 // side effects, you need to write e.g. | |
69 // bool w = x; RTC_DCHECK(w); | |
70 // | |
71 // - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are | |
72 // specialized variants of RTC_CHECK and RTC_DCHECK that print prettier | |
73 // messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and | |
74 // RTC_DCHECK. | |
75 // | |
76 // - FATAL() aborts unconditionally. | |
77 // | |
78 // TODO(ajm): Ideally, checks.h would be combined with logging.h, but | |
79 // consolidation with system_wrappers/logging.h should happen first. | |
80 | |
81 namespace rtc { | |
82 | |
83 // Helper macro which avoids evaluating the arguments to a stream if | |
84 // the condition doesn't hold. | |
85 #define RTC_LAZY_STREAM(stream, condition) \ | |
86 !(condition) ? static_cast<void>(0) : rtc::FatalMessageVoidify() & (stream) | |
87 | |
88 // The actual stream used isn't important. We reference |ignored| in the code | |
89 // but don't evaluate it; this is to avoid "unused variable" warnings (we do so | |
90 // in a particularly convoluted way with an extra ?: because that appears to be | |
91 // the simplest construct that keeps Visual Studio from complaining about | |
92 // condition being unused). | |
93 #define RTC_EAT_STREAM_PARAMETERS(ignored) \ | |
94 (true ? true : ((void)(ignored), true)) \ | |
95 ? static_cast<void>(0) \ | |
96 : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream() | |
97 | |
98 // Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if | |
99 // values of the same types as |a| and |b| can't be compared with the given | |
100 // operation, and that would evaluate |a| and |b| if evaluated. | |
101 #define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \ | |
102 RTC_EAT_STREAM_PARAMETERS(((void)rtc::Safe##op(a, b))) | |
103 | |
104 // RTC_CHECK dies with a fatal error if condition is not true. It is *not* | |
105 // controlled by NDEBUG or anything else, so the check will be executed | |
106 // regardless of compilation mode. | |
107 // | |
108 // We make sure RTC_CHECK et al. always evaluates their arguments, as | |
109 // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom. | |
110 #define RTC_CHECK(condition) \ | |
111 RTC_LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), \ | |
112 !(condition)) \ | |
113 << "Check failed: " #condition << std::endl << "# " | |
114 | |
115 // Helper macro for binary operators. | |
116 // Don't use this macro directly in your code, use RTC_CHECK_EQ et al below. | |
117 // | |
118 // TODO(akalin): Rewrite this so that constructs like if (...) | |
119 // RTC_CHECK_EQ(...) else { ... } work properly. | |
120 #define RTC_CHECK_OP(name, op, val1, val2) \ | |
121 if (std::string* _result = \ | |
122 rtc::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ | |
123 rtc::FatalMessage(__FILE__, __LINE__, _result).stream() | |
124 | |
125 // Build the error message string. This is separate from the "Impl" | |
126 // function template because it is not performance critical and so can | |
127 // be out of line, while the "Impl" code should be inline. Caller | |
128 // takes ownership of the returned string. | |
129 template<class t1, class t2> | |
130 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { | |
131 std::ostringstream ss; | |
132 ss << names << " (" << v1 << " vs. " << v2 << ")"; | |
133 std::string* msg = new std::string(ss.str()); | |
134 return msg; | |
135 } | |
136 | |
137 // MSVC doesn't like complex extern templates and DLLs. | |
138 #if !defined(COMPILER_MSVC) | |
139 // Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated | |
140 // in logging.cc. | |
141 extern template std::string* MakeCheckOpString<int, int>( | |
142 const int&, const int&, const char* names); | |
143 extern template | |
144 std::string* MakeCheckOpString<unsigned long, unsigned long>( | |
145 const unsigned long&, const unsigned long&, const char* names); | |
146 extern template | |
147 std::string* MakeCheckOpString<unsigned long, unsigned int>( | |
148 const unsigned long&, const unsigned int&, const char* names); | |
149 extern template | |
150 std::string* MakeCheckOpString<unsigned int, unsigned long>( | |
151 const unsigned int&, const unsigned long&, const char* names); | |
152 extern template | |
153 std::string* MakeCheckOpString<std::string, std::string>( | |
154 const std::string&, const std::string&, const char* name); | |
155 #endif | |
156 | |
157 // Helper functions for RTC_CHECK_OP macro. | |
158 // The (int, int) specialization works around the issue that the compiler | |
159 // will not instantiate the template version of the function on values of | |
160 // unnamed enum type - see comment below. | |
161 #define DEFINE_RTC_CHECK_OP_IMPL(name) \ | |
162 template <class t1, class t2> \ | |
163 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ | |
164 const char* names) { \ | |
165 if (rtc::Safe##name(v1, v2)) \ | |
166 return nullptr; \ | |
167 else \ | |
168 return rtc::MakeCheckOpString(v1, v2, names); \ | |
169 } \ | |
170 inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ | |
171 if (rtc::Safe##name(v1, v2)) \ | |
172 return nullptr; \ | |
173 else \ | |
174 return rtc::MakeCheckOpString(v1, v2, names); \ | |
175 } | |
176 DEFINE_RTC_CHECK_OP_IMPL(Eq) | |
177 DEFINE_RTC_CHECK_OP_IMPL(Ne) | |
178 DEFINE_RTC_CHECK_OP_IMPL(Le) | |
179 DEFINE_RTC_CHECK_OP_IMPL(Lt) | |
180 DEFINE_RTC_CHECK_OP_IMPL(Ge) | |
181 DEFINE_RTC_CHECK_OP_IMPL(Gt) | |
182 #undef DEFINE_RTC_CHECK_OP_IMPL | |
183 | |
184 #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2) | |
185 #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2) | |
186 #define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2) | |
187 #define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2) | |
188 #define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2) | |
189 #define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2) | |
190 | |
191 // The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates | |
192 // code in debug builds. It does reference the condition parameter in all cases, | |
193 // though, so callers won't risk getting warnings about unused variables. | |
194 #if RTC_DCHECK_IS_ON | |
195 #define RTC_DCHECK(condition) RTC_CHECK(condition) | |
196 #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2) | |
197 #define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2) | |
198 #define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2) | |
199 #define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2) | |
200 #define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2) | |
201 #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2) | |
202 #else | |
203 #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition) | |
204 #define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2) | |
205 #define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2) | |
206 #define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2) | |
207 #define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2) | |
208 #define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2) | |
209 #define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2) | |
210 #endif | |
211 | |
212 // This is identical to LogMessageVoidify but in name. | |
213 class FatalMessageVoidify { | |
214 public: | |
215 FatalMessageVoidify() { } | |
216 // This has to be an operator with a precedence lower than << but | |
217 // higher than ?: | |
218 void operator&(std::ostream&) { } | |
219 }; | |
220 | |
221 #define RTC_UNREACHABLE_CODE_HIT false | |
222 #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT) | |
223 | |
224 #define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream() | |
225 // TODO(ajm): Consider adding RTC_NOTIMPLEMENTED macro when | |
226 // base/logging.h and system_wrappers/logging.h are consolidated such that we | |
227 // can match the Chromium behavior. | |
228 | |
229 // Like a stripped-down LogMessage from logging.h, except that it aborts. | |
230 class FatalMessage { | |
231 public: | |
232 FatalMessage(const char* file, int line); | |
233 // Used for RTC_CHECK_EQ(), etc. Takes ownership of the given string. | |
234 FatalMessage(const char* file, int line, std::string* result); | |
235 NO_RETURN ~FatalMessage(); | |
236 | |
237 std::ostream& stream() { return stream_; } | |
238 | |
239 private: | |
240 void Init(const char* file, int line); | |
241 | |
242 std::ostringstream stream_; | |
243 }; | |
244 | |
245 // Performs the integer division a/b and returns the result. CHECKs that the | |
246 // remainder is zero. | |
247 template <typename T> | |
248 inline T CheckedDivExact(T a, T b) { | |
249 RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b; | |
250 return a / b; | |
251 } | |
252 | |
253 } // namespace rtc | |
254 | |
255 #else // __cplusplus not defined | |
256 // C version. Lacks many features compared to the C++ version, but usage | |
257 // guidelines are the same. | |
258 | |
259 #define RTC_CHECK(condition) \ | |
260 do { \ | |
261 if (!(condition)) { \ | |
262 rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \ | |
263 } \ | |
264 } while (0) | |
265 | |
266 #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b)) | |
267 #define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b)) | |
268 #define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b)) | |
269 #define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b)) | |
270 #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b)) | |
271 #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b)) | |
272 | |
273 #define RTC_DCHECK(condition) \ | |
274 do { \ | |
275 if (RTC_DCHECK_IS_ON && !(condition)) { \ | |
276 rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \ | |
277 } \ | |
278 } while (0) | |
279 | |
280 #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b)) | |
281 #define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b)) | |
282 #define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b)) | |
283 #define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b)) | |
284 #define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b)) | |
285 #define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b)) | |
286 | |
287 #endif // __cplusplus | |
288 | 18 |
289 #endif // WEBRTC_BASE_CHECKS_H_ | 19 #endif // WEBRTC_BASE_CHECKS_H_ |
OLD | NEW |