• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef NDEBUG
47 /* Disable ASSERT* macros in release mode. */
48 #define ASSERTIONS_DISABLED_DEFAULT 1
49 #else
50 #define ASSERTIONS_DISABLED_DEFAULT 0
51 #endif
52 
53 #ifndef BACKTRACE_DISABLED
54 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
55 #endif
56 
57 #ifndef ASSERT_ENABLED
58 // Notice the not below:
59 #define ASSERT_ENABLED !ASSERTIONS_DISABLED_DEFAULT
60 #endif
61 
62 #ifndef ASSERT_MSG_DISABLED
63 #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
64 #endif
65 
66 #ifndef ASSERT_ARG_DISABLED
67 #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
68 #endif
69 
70 #ifndef FATAL_DISABLED
71 #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
72 #endif
73 
74 #ifndef ERROR_DISABLED
75 #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
76 #endif
77 
78 #ifndef LOG_DISABLED
79 #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
80 #endif
81 
82 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
83    emits a warning when %@ is used in the format string.  Until <rdar://problem/5195437> is resolved we can't include
84    the attribute when being used from Objective-C code in case it decides to use %@. */
85 #if COMPILER(GCC) && !defined(__OBJC__)
86 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
87 #else
88 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
89 #endif
90 
91 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
92 
93 #ifdef __cplusplus
94 extern "C" {
95 #endif
96 
97 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
98 
99 typedef struct {
100     WTFLogChannelState state;
101 } WTFLogChannel;
102 
103 WTF_EXPORT void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
104 WTF_EXPORT void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
105 WTF_EXPORT void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
106 WTF_EXPORT void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
107 WTF_EXPORT void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
108 WTF_EXPORT void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
109 WTF_EXPORT void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
110 WTF_EXPORT void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
111 
112 WTF_EXPORT void WTFGetBacktrace(void** stack, int* size);
113 WTF_EXPORT void WTFReportBacktrace(int framesToShow = 31);
114 WTF_EXPORT void WTFPrintBacktrace(void** stack, int size);
115 
116 typedef void (*WTFCrashHookFunction)();
117 WTF_EXPORT void WTFSetCrashHook(WTFCrashHookFunction);
118 WTF_EXPORT void WTFInvokeCrashHook();
119 WTF_EXPORT void WTFInstallReportBacktraceOnCrashHook();
120 
121 #ifdef __cplusplus
122 }
123 
124 namespace WTF {
125 
126 class WTF_EXPORT FrameToNameScope {
127 public:
128     explicit FrameToNameScope(void*);
129     ~FrameToNameScope();
nullableName()130     const char* nullableName() { return m_name; }
131 
132 private:
133     const char* m_name;
134     char* m_cxaDemangled;
135 };
136 
137 } // namespace WTF
138 
139 using WTF::FrameToNameScope;
140 #endif
141 
142 /* IMMEDIATE_CRASH() - Like CRASH() below but crashes in the fastest, simplest possible way with no attempt at logging. */
143 #ifndef IMMEDIATE_CRASH
144 #if COMPILER(GCC)
145 #define IMMEDIATE_CRASH() __builtin_trap()
146 #else
147 #define IMMEDIATE_CRASH() ((void(*)())0)()
148 #endif
149 #endif
150 
151 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
152 
153    Use CRASH() in response to known, unrecoverable errors like out-of-memory.
154    Macro is enabled in both debug and release mode.
155    To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
156 
157    Signals are ignored by the crash reporter on OS X so we must do better.
158 */
159 #ifndef CRASH
160 #define CRASH() \
161     (WTFReportBacktrace(), \
162      WTFInvokeCrashHook(), \
163      (*(int*)0xfbadbeef = 0), \
164      IMMEDIATE_CRASH())
165 #endif
166 
167 #if COMPILER(CLANG)
168 #define NO_RETURN_DUE_TO_CRASH NO_RETURN
169 #else
170 #define NO_RETURN_DUE_TO_CRASH
171 #endif
172 
173 /* BACKTRACE
174 
175   Print a backtrace to the same location as ASSERT messages.
176 */
177 #if BACKTRACE_DISABLED
178 
179 #define BACKTRACE() ((void)0)
180 
181 #else
182 
183 #define BACKTRACE() do { \
184     WTFReportBacktrace(); \
185 } while(false)
186 
187 #endif
188 
189 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
190 
191   These macros are compiled out of release builds.
192   Expressions inside them are evaluated in debug builds only.
193 */
194 #if OS(WIN)
195 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
196 #undef ASSERT
197 #endif
198 
199 #if ASSERT_ENABLED
200 
201 #define ASSERT(assertion) \
202     (!(assertion) ? \
203         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
204          CRASH()) : \
205         (void)0)
206 
207 #define ASSERT_AT(assertion, file, line, function) \
208     (!(assertion) ? \
209         (WTFReportAssertionFailure(file, line, function, #assertion), \
210          CRASH()) :                                                   \
211         (void)0)
212 
213 #define ASSERT_NOT_REACHED() do { \
214     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
215     CRASH(); \
216 } while (0)
217 
218 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
219 
220 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
221 
222 #else
223 
224 #define ASSERT(assertion) ((void)0)
225 #define ASSERT_AT(assertion, file, line, function) ((void)0)
226 #define ASSERT_NOT_REACHED() ((void)0)
227 #define NO_RETURN_DUE_TO_ASSERT
228 
229 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
230 
231 #endif
232 
233 /* ASSERT_WITH_SECURITY_IMPLICATION / RELEASE_ASSERT_WITH_SECURITY_IMPLICATION
234 
235    Use in places where failure of the assertion indicates a possible security
236    vulnerability. Classes of these vulnerabilities include bad casts, out of
237    bounds accesses, use-after-frees, etc. Please be sure to file bugs for these
238    failures using the security template:
239       http://code.google.com/p/chromium/issues/entry?template=Security%20Bug
240 */
241 #ifdef ADDRESS_SANITIZER
242 
243 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
244     (!(assertion) ? \
245         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
246          CRASH()) : \
247         (void)0)
248 
249 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT_WITH_SECURITY_IMPLICATION(assertion)
250 
251 #else
252 
253 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT(assertion)
254 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) RELEASE_ASSERT(assertion)
255 
256 #endif
257 
258 #if defined(ADDRESS_SANITIZER) || ASSERT_ENABLED
259 #define SECURITY_ASSERT_ENABLED 1
260 #else
261 #define SECURITY_ASSERT_ENABLED 0
262 #endif
263 
264 /* ASSERT_WITH_MESSAGE */
265 
266 #if ASSERT_MSG_DISABLED
267 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
268 #else
269 #define ASSERT_WITH_MESSAGE(assertion, ...) do \
270     if (!(assertion)) { \
271         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
272         CRASH(); \
273     } \
274 while (0)
275 #endif
276 
277 /* ASSERT_WITH_MESSAGE_UNUSED */
278 
279 #if ASSERT_MSG_DISABLED
280 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
281 #else
282 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
283     if (!(assertion)) { \
284         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
285         CRASH(); \
286     } \
287 while (0)
288 #endif
289 
290 /* ASSERT_ARG */
291 
292 #if ASSERT_ARG_DISABLED
293 
294 #define ASSERT_ARG(argName, assertion) ((void)0)
295 
296 #else
297 
298 #define ASSERT_ARG(argName, assertion) do \
299     if (!(assertion)) { \
300         WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
301         CRASH(); \
302     } \
303 while (0)
304 
305 #endif
306 
307 /* COMPILE_ASSERT */
308 #ifndef COMPILE_ASSERT
309 #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
310 /* Unlike static_assert below, this also works in plain C code. */
311 #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
312 #elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
313 #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
314 #else
315 #define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
316 #endif
317 #endif
318 
319 /* FATAL */
320 
321 #if FATAL_DISABLED
322 #define FATAL(...) ((void)0)
323 #else
324 #define FATAL(...) do { \
325     WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
326     CRASH(); \
327 } while (0)
328 #endif
329 
330 /* WTF_LOG_ERROR */
331 
332 #if ERROR_DISABLED
333 #define WTF_LOG_ERROR(...) ((void)0)
334 #else
335 #define WTF_LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
336 #endif
337 
338 /* WTF_LOG */
339 
340 #if LOG_DISABLED
341 #define WTF_LOG(channel, ...) ((void)0)
342 #else
343 #define WTF_LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
344 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
345 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
346 #endif
347 
348 /* UNREACHABLE_FOR_PLATFORM */
349 
350 #if COMPILER(CLANG)
351 /* This would be a macro except that its use of #pragma works best around
352    a function. Hence it uses macro naming convention. */
353 #pragma clang diagnostic push
354 #pragma clang diagnostic ignored "-Wmissing-noreturn"
UNREACHABLE_FOR_PLATFORM()355 static inline void UNREACHABLE_FOR_PLATFORM()
356 {
357     ASSERT_NOT_REACHED();
358 }
359 #pragma clang diagnostic pop
360 #else
361 #define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
362 #endif
363 
364 /* RELEASE_ASSERT
365 
366    Use in places where failure of an assertion indicates a definite security
367    vulnerability from which execution must not continue even in a release build.
368    Please sure to file bugs for these failures using the security template:
369       http://code.google.com/p/chromium/issues/entry?template=Security%20Bug
370 */
371 
372 #if ASSERT_ENABLED
373 #define RELEASE_ASSERT(assertion) ASSERT(assertion)
374 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
375 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
376 #else
377 #define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (IMMEDIATE_CRASH()) : (void)0)
378 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
379 #define RELEASE_ASSERT_NOT_REACHED() IMMEDIATE_CRASH()
380 #endif
381 
382 /* DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES */
383 
384 // Allow equality comparisons of Objects by reference or pointer, interchangeably.
385 #define DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(thisType) \
386     inline bool operator==(const thisType& a, const thisType& b) { return &a == &b; } \
387     inline bool operator==(const thisType& a, const thisType* b) { return &a == b; } \
388     inline bool operator==(const thisType* a, const thisType& b) { return a == &b; } \
389     inline bool operator!=(const thisType& a, const thisType& b) { return !(a == b); } \
390     inline bool operator!=(const thisType& a, const thisType* b) { return !(a == b); } \
391     inline bool operator!=(const thisType* a, const thisType& b) { return !(a == b); }
392 
393 #define DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(thisType) \
394     DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(thisType) \
395     inline bool operator==(const PassRefPtr<thisType>& a, const thisType& b) { return a.get() == &b; } \
396     inline bool operator==(const thisType& a, const PassRefPtr<thisType>& b) { return &a == b.get(); } \
397     inline bool operator!=(const PassRefPtr<thisType>& a, const thisType& b) { return !(a == b); } \
398     inline bool operator!=(const thisType& a, const PassRefPtr<thisType>& b) { return !(a == b); }
399 
400 /* DEFINE_TYPE_CASTS */
401 
402 #define DEFINE_TYPE_CASTS(thisType, argumentType, argumentName, pointerPredicate, referencePredicate) \
403 inline thisType* to##thisType(argumentType* argumentName) \
404 { \
405     ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
406     return static_cast<thisType*>(argumentName); \
407 } \
408 inline const thisType* to##thisType(const argumentType* argumentName) \
409 { \
410     ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
411     return static_cast<const thisType*>(argumentName); \
412 } \
413 inline thisType& to##thisType(argumentType& argumentName) \
414 { \
415     ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
416     return static_cast<thisType&>(argumentName); \
417 } \
418 inline const thisType& to##thisType(const argumentType& argumentName) \
419 { \
420     ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
421     return static_cast<const thisType&>(argumentName); \
422 } \
423 void to##thisType(const thisType*); \
424 void to##thisType(const thisType&)
425 
426 #endif /* WTF_Assertions_h */
427