1 /*
2 * Copyright (C) 2003, 2006, 2007 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 COMPUTER, 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 COMPUTER, 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 /*
30 no namespaces because this file has to be includable from C and Objective-C
31
32 Note, this file uses many GCC extensions, but it should be compatible with
33 C, Objective C, C++, and Objective C++.
34
35 For non-debug builds, everything is disabled by default.
36 Defining any of the symbols explicitly prevents this from having any effect.
37
38 MSVC7 note: variadic macro support was added in MSVC8, so for now we disable
39 those macros in MSVC7. For more info, see the MSDN document on variadic
40 macros here:
41
42 http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
43 */
44
45 #include "Platform.h"
46
47 #include <stddef.h>
48
49 #if !COMPILER(MSVC)
50 #include <inttypes.h>
51 #endif
52
53 #if OS(SYMBIAN)
54 #include <e32def.h>
55 #include <e32debug.h>
56 #endif
57
58 #if PLATFORM(BREWMP)
59 #include <AEEError.h>
60 #include <AEEdbg.h>
61 #endif
62
63 #ifdef NDEBUG
64 /* Disable ASSERT* macros in release mode. */
65 #define ASSERTIONS_DISABLED_DEFAULT 1
66 #else
67 #define ASSERTIONS_DISABLED_DEFAULT 0
68 #endif
69
70 #if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW)
71 #define HAVE_VARIADIC_MACRO 0
72 #else
73 #define HAVE_VARIADIC_MACRO 1
74 #endif
75
76 #ifndef BACKTRACE_DISABLED
77 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
78 #endif
79
80 #ifndef ASSERT_DISABLED
81 #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
82 #endif
83
84 #ifndef ASSERT_MSG_DISABLED
85 #if HAVE(VARIADIC_MACRO)
86 #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
87 #else
88 #define ASSERT_MSG_DISABLED 1
89 #endif
90 #endif
91
92 #ifndef ASSERT_ARG_DISABLED
93 #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
94 #endif
95
96 #ifndef FATAL_DISABLED
97 #if HAVE(VARIADIC_MACRO)
98 #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
99 #else
100 #define FATAL_DISABLED 1
101 #endif
102 #endif
103
104 #ifndef ERROR_DISABLED
105 #if HAVE(VARIADIC_MACRO)
106 #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
107 #else
108 #define ERROR_DISABLED 1
109 #endif
110 #endif
111
112 #ifndef LOG_DISABLED
113 #if HAVE(VARIADIC_MACRO)
114 #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
115 #else
116 #define LOG_DISABLED 1
117 #endif
118 #endif
119
120 #if COMPILER(GCC)
121 #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
122 #else
123 #define WTF_PRETTY_FUNCTION __FUNCTION__
124 #endif
125
126 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
127 emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include
128 the attribute when being used from Objective-C code in case it decides to use %@. */
129 #if COMPILER(GCC) && !defined(__OBJC__)
130 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
131 #else
132 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
133 #endif
134
135 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
136
137 #ifdef __cplusplus
138 extern "C" {
139 #endif
140
141 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
142
143 typedef struct {
144 unsigned mask;
145 const char *defaultName;
146 WTFLogChannelState state;
147 } WTFLogChannel;
148
149 WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
150 WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
151 WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
152 WTF_EXPORT_PRIVATE void WTFReportBacktrace();
153 WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
154 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
155 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
156 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
157
158 #ifdef __cplusplus
159 }
160 #endif
161
162 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
163
164 Use CRASH() in response to known, unrecoverable errors like out-of-memory.
165 Macro is enabled in both debug and release mode.
166 To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
167
168 Signals are ignored by the crash reporter on OS X so we must do better.
169 */
170 #ifndef CRASH
171 #if OS(SYMBIAN)
172 #define CRASH() do { \
173 __DEBUGGER(); \
174 User::Panic(_L("Webkit CRASH"),0); \
175 } while(false)
176 #elif PLATFORM(BREWMP)
177 #define CRASH() do { \
178 dbg_Message("WebKit CRASH", DBG_MSG_LEVEL_FATAL, __FILE__, __LINE__); \
179 *(int *)(uintptr_t)0xbbadbeef = 0; \
180 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
181 } while(false)
182 #else
183 #define CRASH() do { \
184 WTFReportBacktrace(); \
185 *(int *)(uintptr_t)0xbbadbeef = 0; \
186 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
187 } while(false)
188 #endif
189 #endif
190
191 /* BACKTRACE
192
193 Print a backtrace to the same location as ASSERT messages.
194 */
195
196 #if BACKTRACE_DISABLED
197
198 #define BACKTRACE() ((void)0)
199
200 #else
201
202 #define BACKTRACE() do { \
203 WTFReportBacktrace(); \
204 } while(false)
205
206 #endif
207
208 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
209
210 These macros are compiled out of release builds.
211 Expressions inside them are evaluated in debug builds only.
212 */
213
214 #if OS(WINCE) && !PLATFORM(TORCHMOBILE)
215 /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
216 #include <windows.h>
217 #undef min
218 #undef max
219 #undef ERROR
220 #endif
221
222 #if OS(WINDOWS) || OS(SYMBIAN)
223 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
224 #undef ASSERT
225 #endif
226
227 #if PLATFORM(BREWMP)
228 /* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */
229 #include <AEEClassIDs.h>
230
231 /* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */
232 #undef COMPILE_ASSERT
233 #endif
234
235 #if ASSERT_DISABLED
236
237 #define ASSERT(assertion) ((void)0)
238 #define ASSERT_NOT_REACHED() ((void)0)
239
240 #if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
241 template<typename T>
assertUnused(T & x)242 inline void assertUnused(T& x) { (void)x; }
243 #define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
244 #else
245 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
246 #endif
247
248 #else
249
250 #define ASSERT(assertion) do \
251 if (!(assertion)) { \
252 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
253 CRASH(); \
254 } \
255 while (0)
256
257 #define ASSERT_NOT_REACHED() do { \
258 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
259 CRASH(); \
260 } while (0)
261
262 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
263
264 #endif
265
266 /* ASSERT_WITH_MESSAGE */
267
268 #if COMPILER(MSVC7_OR_LOWER)
269 #define ASSERT_WITH_MESSAGE(assertion) ((void)0)
270 #elif COMPILER(WINSCW)
271 #define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
272 #elif ASSERT_MSG_DISABLED
273 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
274 #else
275 #define ASSERT_WITH_MESSAGE(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
284 /* ASSERT_ARG */
285
286 #if ASSERT_ARG_DISABLED
287
288 #define ASSERT_ARG(argName, assertion) ((void)0)
289
290 #else
291
292 #define ASSERT_ARG(argName, assertion) do \
293 if (!(assertion)) { \
294 WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
295 CRASH(); \
296 } \
297 while (0)
298
299 #endif
300
301 /* COMPILE_ASSERT */
302 #ifndef COMPILE_ASSERT
303 #define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
304 #endif
305
306 /* FATAL */
307
308 #if COMPILER(MSVC7_OR_LOWER)
309 #define FATAL() ((void)0)
310 #elif COMPILER(WINSCW)
311 #define FATAL(arg...) ((void)0)
312 #elif FATAL_DISABLED
313 #define FATAL(...) ((void)0)
314 #else
315 #define FATAL(...) do { \
316 WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
317 CRASH(); \
318 } while (0)
319 #endif
320
321 /* LOG_ERROR */
322
323 #if COMPILER(MSVC7_OR_LOWER)
324 #define LOG_ERROR() ((void)0)
325 #elif COMPILER(WINSCW)
326 #define LOG_ERROR(arg...) ((void)0)
327 #elif ERROR_DISABLED
328 #define LOG_ERROR(...) ((void)0)
329 #else
330 #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
331 #endif
332
333 /* LOG */
334
335 #if COMPILER(MSVC7_OR_LOWER)
336 #define LOG() ((void)0)
337 #elif COMPILER(WINSCW)
338 #define LOG(arg...) ((void)0)
339 #elif LOG_DISABLED
340 #define LOG(channel, ...) ((void)0)
341 #else
342 #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
343 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
344 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
345 #endif
346
347 /* LOG_VERBOSE */
348
349 #if COMPILER(MSVC7_OR_LOWER)
350 #define LOG_VERBOSE(channel) ((void)0)
351 #elif COMPILER(WINSCW)
352 #define LOG_VERBOSE(channel, arg...) ((void)0)
353 #elif LOG_DISABLED
354 #define LOG_VERBOSE(channel, ...) ((void)0)
355 #else
356 #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
357 #endif
358
359 #endif /* WTF_Assertions_h */
360