1 /*
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifndef WTF_Assertions_h
28 #define WTF_Assertions_h
29
30 /*
31 No namespaces because this file has to be includable from C and Objective-C.
32
33 Note, this file uses many GCC extensions, but it should be compatible with
34 C, Objective C, C++, and Objective C++.
35
36 For non-debug builds, everything is disabled by default, except for the
37 RELEASE_ASSERT family of macros.
38
39 Defining any of the symbols explicitly prevents this from having any effect.
40
41 */
42
43 #include "wtf/Compiler.h"
44 #include "wtf/WTFExport.h"
45
46 // Users must test "#if ENABLE(ASSERT)", which helps ensure that code
47 // testing this macro has included this header.
48 #ifndef ENABLE_ASSERT
49 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
50 /* Disable ASSERT* macros in release mode by default. */
51 #define ENABLE_ASSERT 0
52 #else
53 #define ENABLE_ASSERT 1
54 #endif /* defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) */
55 #endif
56
57 #ifndef BACKTRACE_DISABLED
58 #define BACKTRACE_DISABLED !ENABLE(ASSERT)
59 #endif
60
61 #ifndef ASSERT_MSG_DISABLED
62 #define ASSERT_MSG_DISABLED !ENABLE(ASSERT)
63 #endif
64
65 #ifndef ASSERT_ARG_DISABLED
66 #define ASSERT_ARG_DISABLED !ENABLE(ASSERT)
67 #endif
68
69 #ifndef FATAL_DISABLED
70 #define FATAL_DISABLED !ENABLE(ASSERT)
71 #endif
72
73 #ifndef ERROR_DISABLED
74 #define ERROR_DISABLED !ENABLE(ASSERT)
75 #endif
76
77 #ifndef LOG_DISABLED
78 #define LOG_DISABLED !ENABLE(ASSERT)
79 #endif
80
81 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
82 emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include
83 the attribute when being used from Objective-C code in case it decides to use %@. */
84 #if COMPILER(GCC) && !defined(__OBJC__)
85 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
86 #else
87 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
88 #endif
89
90 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
91
92 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
93
94 typedef struct {
95 WTFLogChannelState state;
96 } WTFLogChannel;
97
98 WTF_EXPORT void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
99 WTF_EXPORT void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
100 WTF_EXPORT void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
101 WTF_EXPORT void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
102 WTF_EXPORT void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
103 WTF_EXPORT void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
104 WTF_EXPORT void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
105 WTF_EXPORT void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
106
107 WTF_EXPORT void WTFGetBacktrace(void** stack, int* size);
108 WTF_EXPORT void WTFReportBacktrace(int framesToShow = 31);
109 WTF_EXPORT void WTFPrintBacktrace(void** stack, int size);
110
111 typedef void (*WTFCrashHookFunction)();
112 WTF_EXPORT void WTFSetCrashHook(WTFCrashHookFunction);
113 WTF_EXPORT void WTFInvokeCrashHook();
114 WTF_EXPORT void WTFInstallReportBacktraceOnCrashHook();
115
116 namespace WTF {
117
118 class WTF_EXPORT FrameToNameScope {
119 public:
120 explicit FrameToNameScope(void*);
121 ~FrameToNameScope();
nullableName()122 const char* nullableName() { return m_name; }
123
124 private:
125 const char* m_name;
126 char* m_cxaDemangled;
127 };
128
129 } // namespace WTF
130
131 using WTF::FrameToNameScope;
132
133 /* IMMEDIATE_CRASH() - Like CRASH() below but crashes in the fastest, simplest possible way with no attempt at logging. */
134 #ifndef IMMEDIATE_CRASH
135 #if COMPILER(GCC)
136 #define IMMEDIATE_CRASH() __builtin_trap()
137 #else
138 #define IMMEDIATE_CRASH() ((void(*)())0)()
139 #endif
140 #endif
141
142 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
143
144 Use CRASH() in response to known, unrecoverable errors like out-of-memory.
145 Macro is enabled in both debug and release mode.
146 To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
147
148 Signals are ignored by the crash reporter on OS X so we must do better.
149 */
150 #ifndef CRASH
151 #define CRASH() \
152 (WTFReportBacktrace(), \
153 WTFInvokeCrashHook(), \
154 (*(int*)0xfbadbeef = 0), \
155 IMMEDIATE_CRASH())
156 #endif
157
158 #if COMPILER(CLANG)
159 #define NO_RETURN_DUE_TO_CRASH NO_RETURN
160 #else
161 #define NO_RETURN_DUE_TO_CRASH
162 #endif
163
164 /* BACKTRACE
165
166 Print a backtrace to the same location as ASSERT messages.
167 */
168 #if BACKTRACE_DISABLED
169
170 #define BACKTRACE() ((void)0)
171
172 #else
173
174 #define BACKTRACE() do { \
175 WTFReportBacktrace(); \
176 } while(false)
177
178 #endif
179
180 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
181
182 These macros are compiled out of release builds.
183 Expressions inside them are evaluated in debug builds only.
184 */
185 #if OS(WIN)
186 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
187 #undef ASSERT
188 #endif
189
190 #if ENABLE(ASSERT)
191
192 #define ASSERT(assertion) \
193 (!(assertion) ? \
194 (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
195 CRASH()) : \
196 (void)0)
197
198 #define ASSERT_AT(assertion, file, line, function) \
199 (!(assertion) ? \
200 (WTFReportAssertionFailure(file, line, function, #assertion), \
201 CRASH()) : \
202 (void)0)
203
204 #define ASSERT_NOT_REACHED() do { \
205 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
206 CRASH(); \
207 } while (0)
208
209 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
210
211 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
212
213 #else
214
215 #define ASSERT(assertion) ((void)0)
216 #define ASSERT_AT(assertion, file, line, function) ((void)0)
217 #define ASSERT_NOT_REACHED() ((void)0)
218 #define NO_RETURN_DUE_TO_ASSERT
219
220 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
221
222 #endif
223
224 /* ASSERT_WITH_SECURITY_IMPLICATION / RELEASE_ASSERT_WITH_SECURITY_IMPLICATION
225
226 Use in places where failure of the assertion indicates a possible security
227 vulnerability. Classes of these vulnerabilities include bad casts, out of
228 bounds accesses, use-after-frees, etc. Please be sure to file bugs for these
229 failures using the security template:
230 http://code.google.com/p/chromium/issues/entry?template=Security%20Bug
231 */
232 #ifdef ADDRESS_SANITIZER
233
234 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
235 (!(assertion) ? \
236 (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
237 CRASH()) : \
238 (void)0)
239
240 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT_WITH_SECURITY_IMPLICATION(assertion)
241
242 #else
243
244 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT(assertion)
245 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) RELEASE_ASSERT(assertion)
246
247 #endif
248
249 // Users must test "#if ENABLE(SECURITY_ASSERT)", which helps ensure
250 // that code testing this macro has included this header.
251 #if defined(ADDRESS_SANITIZER) || ENABLE(ASSERT)
252 #define ENABLE_SECURITY_ASSERT 1
253 #else
254 #define ENABLE_SECURITY_ASSERT 0
255 #endif
256
257 /* ASSERT_WITH_MESSAGE */
258
259 #if ASSERT_MSG_DISABLED
260 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
261 #else
262 #define ASSERT_WITH_MESSAGE(assertion, ...) do \
263 if (!(assertion)) { \
264 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
265 CRASH(); \
266 } \
267 while (0)
268 #endif
269
270 /* ASSERT_WITH_MESSAGE_UNUSED */
271
272 #if ASSERT_MSG_DISABLED
273 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
274 #else
275 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
276 if (!(assertion)) { \
277 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
278 CRASH(); \
279 } \
280 while (0)
281 #endif
282
283 /* ASSERT_ARG */
284
285 #if ASSERT_ARG_DISABLED
286
287 #define ASSERT_ARG(argName, assertion) ((void)0)
288
289 #else
290
291 #define ASSERT_ARG(argName, assertion) do \
292 if (!(assertion)) { \
293 WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
294 CRASH(); \
295 } \
296 while (0)
297
298 #endif
299
300 /* COMPILE_ASSERT */
301 #ifndef COMPILE_ASSERT
302 #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
303 /* Unlike static_assert below, this also works in plain C code. */
304 #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
305 #elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
306 #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
307 #else
308 #define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
309 #endif
310 #endif
311
312 /* FATAL */
313
314 #if FATAL_DISABLED
315 #define FATAL(...) ((void)0)
316 #else
317 #define FATAL(...) do { \
318 WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
319 CRASH(); \
320 } while (0)
321 #endif
322
323 /* WTF_LOG_ERROR */
324
325 #if ERROR_DISABLED
326 #define WTF_LOG_ERROR(...) ((void)0)
327 #else
328 #define WTF_LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
329 #endif
330
331 /* WTF_LOG */
332
333 #if LOG_DISABLED
334 #define WTF_LOG(channel, ...) ((void)0)
335 #else
336 #define WTF_LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
337 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
338 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
339 #endif
340
341 /* UNREACHABLE_FOR_PLATFORM */
342
343 #if COMPILER(CLANG)
344 /* This would be a macro except that its use of #pragma works best around
345 a function. Hence it uses macro naming convention. */
346 #pragma clang diagnostic push
347 #pragma clang diagnostic ignored "-Wmissing-noreturn"
UNREACHABLE_FOR_PLATFORM()348 static inline void UNREACHABLE_FOR_PLATFORM()
349 {
350 ASSERT_NOT_REACHED();
351 }
352 #pragma clang diagnostic pop
353 #else
354 #define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
355 #endif
356
357 /* RELEASE_ASSERT
358
359 Use in places where failure of an assertion indicates a definite security
360 vulnerability from which execution must not continue even in a release build.
361 Please sure to file bugs for these failures using the security template:
362 http://code.google.com/p/chromium/issues/entry?template=Security%20Bug
363 */
364
365 #if ENABLE(ASSERT)
366 #define RELEASE_ASSERT(assertion) ASSERT(assertion)
367 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
368 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
369 #else
370 #define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (IMMEDIATE_CRASH()) : (void)0)
371 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
372 #define RELEASE_ASSERT_NOT_REACHED() IMMEDIATE_CRASH()
373 #endif
374
375 /* DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES */
376
377 // Allow equality comparisons of Objects by reference or pointer, interchangeably.
378 // This can be only used on types whose equality makes no other sense than pointer equality.
379 #define DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(thisType) \
380 inline bool operator==(const thisType& a, const thisType& b) { return &a == &b; } \
381 inline bool operator==(const thisType& a, const thisType* b) { return &a == b; } \
382 inline bool operator==(const thisType* a, const thisType& b) { return a == &b; } \
383 inline bool operator!=(const thisType& a, const thisType& b) { return !(a == b); } \
384 inline bool operator!=(const thisType& a, const thisType* b) { return !(a == b); } \
385 inline bool operator!=(const thisType* a, const thisType& b) { return !(a == b); }
386
387 #define DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(thisType) \
388 DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(thisType) \
389 inline bool operator==(const PassRefPtr<thisType>& a, const thisType& b) { return a.get() == &b; } \
390 inline bool operator==(const thisType& a, const PassRefPtr<thisType>& b) { return &a == b.get(); } \
391 inline bool operator!=(const PassRefPtr<thisType>& a, const thisType& b) { return !(a == b); } \
392 inline bool operator!=(const thisType& a, const PassRefPtr<thisType>& b) { return !(a == b); }
393
394 /* DEFINE_TYPE_CASTS */
395
396 #define DEFINE_TYPE_CASTS(thisType, argumentType, argumentName, pointerPredicate, referencePredicate) \
397 inline thisType* to##thisType(argumentType* argumentName) \
398 { \
399 ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
400 return static_cast<thisType*>(argumentName); \
401 } \
402 inline const thisType* to##thisType(const argumentType* argumentName) \
403 { \
404 ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
405 return static_cast<const thisType*>(argumentName); \
406 } \
407 inline thisType& to##thisType(argumentType& argumentName) \
408 { \
409 ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
410 return static_cast<thisType&>(argumentName); \
411 } \
412 inline const thisType& to##thisType(const argumentType& argumentName) \
413 { \
414 ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
415 return static_cast<const thisType&>(argumentName); \
416 } \
417 void to##thisType(const thisType*); \
418 void to##thisType(const thisType&)
419
420 #endif /* WTF_Assertions_h */
421