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