• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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