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> 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