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_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