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