Home | History | Annotate | Download | only in wtf
      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