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