11d6120d2e2f276584be597850556fa1fbd3456f
[WebKit-https.git] / Source / WTF / wtf / Assertions.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2013 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef WTF_Assertions_h
27 #define WTF_Assertions_h
28
29 #include <wtf/Platform.h>
30
31 /*
32    no namespaces because this file has to be includable from C and Objective-C
33
34    Note, this file uses many GCC extensions, but it should be compatible with
35    C, Objective C, C++, and Objective C++.
36
37    For non-debug builds, everything is disabled by default.
38    Defining any of the symbols explicitly prevents this from having any effect.
39 */
40
41 #include <inttypes.h>
42 #include <stdarg.h>
43 #include <stdbool.h>
44 #include <stddef.h>
45 #include <wtf/ExportMacros.h>
46
47 #ifdef NDEBUG
48 /* Disable ASSERT* macros in release mode. */
49 #define ASSERTIONS_DISABLED_DEFAULT 1
50 #else
51 #define ASSERTIONS_DISABLED_DEFAULT 0
52 #endif
53
54 #ifndef BACKTRACE_DISABLED
55 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
56 #endif
57
58 #ifndef ASSERT_DISABLED
59 #define ASSERT_DISABLED 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 #if COMPILER(GCC)
83 #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
84 #else
85 #define WTF_PRETTY_FUNCTION __FUNCTION__
86 #endif
87
88 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
89    emits a warning when %@ is used in the format string.  Until <rdar://problem/5195437> is resolved we can't include
90    the attribute when being used from Objective-C code in case it decides to use %@. */
91 #if COMPILER(GCC) && !defined(__OBJC__)
92 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
93 #else
94 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
95 #endif
96
97 #if PLATFORM(IOS)
98 /* For a project that uses WTF but has no config.h, we need to explicitly set the export defines here. */
99 #ifndef WTF_EXPORT_PRIVATE
100 #define WTF_EXPORT_PRIVATE
101 #endif
102 #endif // PLATFORM(IOS)
103
104 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
105
106 #ifdef __cplusplus
107 extern "C" {
108 #endif
109
110 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
111
112    Use CRASH() in response to known, unrecoverable errors like out-of-memory.
113    Macro is enabled in both debug and release mode.
114    To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
115
116    Signals are ignored by the crash reporter on OS X so we must do better.
117 */
118 #if COMPILER(CLANG) || COMPILER(GCC) || COMPILER(MSVC)
119 #define NO_RETURN_DUE_TO_CRASH NO_RETURN
120 #else
121 #define NO_RETURN_DUE_TO_CRASH
122 #endif
123
124 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
125
126 typedef struct {
127     WTFLogChannelState state;
128     const char* name;
129 } WTFLogChannel;
130
131 WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
132 WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
133 WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
134 WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
135 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
136 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
137 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
138 WTF_EXPORT_PRIVATE void WTFLogAlwaysV(const char* format, va_list);
139 WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
140 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
141 WTF_EXPORT_PRIVATE WTFLogChannel* WTFLogChannelByName(WTFLogChannel*[], size_t count, const char*);
142 WTF_EXPORT_PRIVATE void WTFInitializeLogChannelStatesFromString(WTFLogChannel*[], size_t count, const char*);
143
144 WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
145 WTF_EXPORT_PRIVATE void WTFReportBacktrace();
146 WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
147
148 typedef void (*WTFCrashHookFunction)();
149 WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
150 WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
151
152 WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached();
153
154 #ifdef __cplusplus
155 }
156 #endif
157
158 #ifndef CRASH
159 #define CRASH() WTFCrash()
160 #endif
161
162 #ifdef __cplusplus
163 extern "C" {
164 #endif
165     WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrash();
166 #ifdef __cplusplus
167 }
168 #endif
169
170 #ifndef CRASH_WITH_SECURITY_IMPLICATION
171 #define CRASH_WITH_SECURITY_IMPLICATION() WTFCrashWithSecurityImplication()
172 #endif
173
174 #ifdef __cplusplus
175 extern "C" {
176 #endif
177     WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrashWithSecurityImplication();
178 #ifdef __cplusplus
179 }
180 #endif
181
182 /* BACKTRACE
183
184   Print a backtrace to the same location as ASSERT messages.
185 */
186
187 #if BACKTRACE_DISABLED
188
189 #define BACKTRACE() ((void)0)
190
191 #else
192
193 #define BACKTRACE() do { \
194     WTFReportBacktrace(); \
195 } while(false)
196
197 #endif
198
199 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
200
201   These macros are compiled out of release builds.
202   Expressions inside them are evaluated in debug builds only.
203 */
204
205 #if OS(WINDOWS)
206 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
207 #undef ASSERT
208 #endif
209
210 #if ASSERT_DISABLED
211
212 #define ASSERT(assertion) ((void)0)
213 #define ASSERT_AT(assertion, file, line, function) ((void)0)
214 #define ASSERT_NOT_REACHED() ((void)0)
215 #define NO_RETURN_DUE_TO_ASSERT
216
217 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
218
219 #if ENABLE(SECURITY_ASSERTIONS)
220 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
221     (!(assertion) ? \
222         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
223          CRASH_WITH_SECURITY_IMPLICATION()) : \
224         (void)0)
225
226 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
227 #else
228 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ((void)0)
229 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 1
230 #endif
231
232 #else
233
234 #define ASSERT(assertion) \
235     (!(assertion) ? \
236         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
237          CRASH()) : \
238         (void)0)
239
240 #define ASSERT_AT(assertion, file, line, function) \
241     (!(assertion) ? \
242         (WTFReportAssertionFailure(file, line, function, #assertion), \
243          CRASH()) :                                                   \
244         (void)0)
245
246 #define ASSERT_NOT_REACHED() do { \
247     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
248     CRASH(); \
249 } while (0)
250
251 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
252
253 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
254
255 /* ASSERT_WITH_SECURITY_IMPLICATION
256  
257    Failure of this assertion indicates a possible security vulnerability.
258    Class of vulnerabilities that it tests include bad casts, out of bounds
259    accesses, use-after-frees, etc. Please file a bug using the security
260    template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
261  
262 */
263 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
264     (!(assertion) ? \
265         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
266          CRASH_WITH_SECURITY_IMPLICATION()) : \
267         (void)0)
268 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
269 #endif
270
271 /* ASSERT_WITH_MESSAGE */
272
273 #if ASSERT_MSG_DISABLED
274 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
275 #else
276 #define ASSERT_WITH_MESSAGE(assertion, ...) do \
277     if (!(assertion)) { \
278         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
279         CRASH(); \
280     } \
281 while (0)
282 #endif
283
284 /* ASSERT_WITH_MESSAGE_UNUSED */
285
286 #if ASSERT_MSG_DISABLED
287 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
288 #else
289 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
290     if (!(assertion)) { \
291         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
292         CRASH(); \
293     } \
294 while (0)
295 #endif
296                         
297                         
298 /* ASSERT_ARG */
299
300 #if ASSERT_ARG_DISABLED
301
302 #define ASSERT_ARG(argName, assertion) ((void)0)
303
304 #else
305
306 #define ASSERT_ARG(argName, assertion) do \
307     if (!(assertion)) { \
308         WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
309         CRASH(); \
310     } \
311 while (0)
312
313 #endif
314
315 /* COMPILE_ASSERT */
316 #ifndef COMPILE_ASSERT
317 #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
318 /* Unlike static_assert below, this also works in plain C code. */
319 #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
320 #else
321 #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
322 #endif
323 #endif
324
325 /* FATAL */
326
327 #if FATAL_DISABLED
328 #define FATAL(...) ((void)0)
329 #else
330 #define FATAL(...) do { \
331     WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
332     CRASH(); \
333 } while (0)
334 #endif
335
336 /* LOG_ERROR */
337
338 #if ERROR_DISABLED
339 #define LOG_ERROR(...) ((void)0)
340 #else
341 #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
342 #endif
343
344 /* LOG */
345
346 #if LOG_DISABLED
347 #define LOG(channel, ...) ((void)0)
348 #else
349 #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
350 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
351 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
352 #endif
353
354 /* LOG_VERBOSE */
355
356 #if LOG_DISABLED
357 #define LOG_VERBOSE(channel, ...) ((void)0)
358 #else
359 #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
360 #endif
361
362 /* RELEASE_ASSERT */
363
364 #if ASSERT_DISABLED
365 #define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
366 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
367 #define RELEASE_ASSERT_NOT_REACHED() CRASH()
368 #else
369 #define RELEASE_ASSERT(assertion) ASSERT(assertion)
370 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
371 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
372 #endif
373
374 /* UNREACHABLE_FOR_PLATFORM */
375
376 #if COMPILER(CLANG)
377 // This would be a macro except that its use of #pragma works best around
378 // a function. Hence it uses macro naming convention.
379 #pragma clang diagnostic push
380 #pragma clang diagnostic ignored "-Wmissing-noreturn"
381 static inline void UNREACHABLE_FOR_PLATFORM()
382 {
383     RELEASE_ASSERT_NOT_REACHED();
384 }
385 #pragma clang diagnostic pop
386 #else
387 #define UNREACHABLE_FOR_PLATFORM() RELEASE_ASSERT_NOT_REACHED()
388 #endif
389
390
391 #endif /* WTF_Assertions_h */