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