Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2003, 2006, 2007 Apple Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef WTF_Assertions_h
     27 #define WTF_Assertions_h
     28 
     29 /*
     30    no namespaces because this file has to be includable from C and Objective-C
     31 
     32    Note, this file uses many GCC extensions, but it should be compatible with
     33    C, Objective C, C++, and Objective C++.
     34 
     35    For non-debug builds, everything is disabled by default.
     36    Defining any of the symbols explicitly prevents this from having any effect.
     37 
     38    MSVC7 note: variadic macro support was added in MSVC8, so for now we disable
     39    those macros in MSVC7. For more info, see the MSDN document on variadic
     40    macros here:
     41 
     42    http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
     43 */
     44 
     45 #include "Platform.h"
     46 
     47 #include <stddef.h>
     48 
     49 #if !COMPILER(MSVC)
     50 #include <inttypes.h>
     51 #endif
     52 
     53 #if OS(SYMBIAN)
     54 #include <e32def.h>
     55 #include <e32debug.h>
     56 #endif
     57 
     58 #if PLATFORM(BREWMP)
     59 #include <AEEError.h>
     60 #include <AEEdbg.h>
     61 #endif
     62 
     63 #ifdef NDEBUG
     64 /* Disable ASSERT* macros in release mode. */
     65 #define ASSERTIONS_DISABLED_DEFAULT 1
     66 #else
     67 #define ASSERTIONS_DISABLED_DEFAULT 0
     68 #endif
     69 
     70 #if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW)
     71 #define HAVE_VARIADIC_MACRO 0
     72 #else
     73 #define HAVE_VARIADIC_MACRO 1
     74 #endif
     75 
     76 #ifndef BACKTRACE_DISABLED
     77 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
     78 #endif
     79 
     80 #ifndef ASSERT_DISABLED
     81 #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
     82 #endif
     83 
     84 #ifndef ASSERT_MSG_DISABLED
     85 #if HAVE(VARIADIC_MACRO)
     86 #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
     87 #else
     88 #define ASSERT_MSG_DISABLED 1
     89 #endif
     90 #endif
     91 
     92 #ifndef ASSERT_ARG_DISABLED
     93 #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
     94 #endif
     95 
     96 #ifndef FATAL_DISABLED
     97 #if HAVE(VARIADIC_MACRO)
     98 #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
     99 #else
    100 #define FATAL_DISABLED 1
    101 #endif
    102 #endif
    103 
    104 #ifndef ERROR_DISABLED
    105 #if HAVE(VARIADIC_MACRO)
    106 #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
    107 #else
    108 #define ERROR_DISABLED 1
    109 #endif
    110 #endif
    111 
    112 #ifndef LOG_DISABLED
    113 #if HAVE(VARIADIC_MACRO)
    114 #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
    115 #else
    116 #define LOG_DISABLED 1
    117 #endif
    118 #endif
    119 
    120 #if COMPILER(GCC)
    121 #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
    122 #else
    123 #define WTF_PRETTY_FUNCTION __FUNCTION__
    124 #endif
    125 
    126 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
    127    emits a warning when %@ is used in the format string.  Until <rdar://problem/5195437> is resolved we can't include
    128    the attribute when being used from Objective-C code in case it decides to use %@. */
    129 #if COMPILER(GCC) && !defined(__OBJC__)
    130 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
    131 #else
    132 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
    133 #endif
    134 
    135 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
    136 
    137 #ifdef __cplusplus
    138 extern "C" {
    139 #endif
    140 
    141 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
    142 
    143 typedef struct {
    144     unsigned mask;
    145     const char *defaultName;
    146     WTFLogChannelState state;
    147 } WTFLogChannel;
    148 
    149 WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
    150 WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
    151 WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
    152 WTF_EXPORT_PRIVATE void WTFReportBacktrace();
    153 WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
    154 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
    155 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
    156 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
    157 
    158 #ifdef __cplusplus
    159 }
    160 #endif
    161 
    162 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
    163 
    164    Use CRASH() in response to known, unrecoverable errors like out-of-memory.
    165    Macro is enabled in both debug and release mode.
    166    To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
    167 
    168    Signals are ignored by the crash reporter on OS X so we must do better.
    169 */
    170 #ifndef CRASH
    171 #if OS(SYMBIAN)
    172 #define CRASH() do { \
    173     __DEBUGGER(); \
    174     User::Panic(_L("Webkit CRASH"),0); \
    175     } while(false)
    176 #elif PLATFORM(BREWMP)
    177 #define CRASH() do { \
    178     dbg_Message("WebKit CRASH", DBG_MSG_LEVEL_FATAL, __FILE__, __LINE__); \
    179     *(int *)(uintptr_t)0xbbadbeef = 0; \
    180     ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
    181 } while(false)
    182 #else
    183 #define CRASH() do { \
    184     WTFReportBacktrace(); \
    185     *(int *)(uintptr_t)0xbbadbeef = 0; \
    186     ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
    187 } while(false)
    188 #endif
    189 #endif
    190 
    191 /* BACKTRACE
    192 
    193   Print a backtrace to the same location as ASSERT messages.
    194 */
    195 
    196 #if BACKTRACE_DISABLED
    197 
    198 #define BACKTRACE() ((void)0)
    199 
    200 #else
    201 
    202 #define BACKTRACE() do { \
    203     WTFReportBacktrace(); \
    204 } while(false)
    205 
    206 #endif
    207 
    208 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
    209 
    210   These macros are compiled out of release builds.
    211   Expressions inside them are evaluated in debug builds only.
    212 */
    213 
    214 #if OS(WINCE) && !PLATFORM(TORCHMOBILE)
    215 /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
    216 #include <windows.h>
    217 #undef min
    218 #undef max
    219 #undef ERROR
    220 #endif
    221 
    222 #if OS(WINDOWS) || OS(SYMBIAN)
    223 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
    224 #undef ASSERT
    225 #endif
    226 
    227 #if PLATFORM(BREWMP)
    228 /* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */
    229 #include <AEEClassIDs.h>
    230 
    231 /* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */
    232 #undef COMPILE_ASSERT
    233 #endif
    234 
    235 #if ASSERT_DISABLED
    236 
    237 #define ASSERT(assertion) ((void)0)
    238 #define ASSERT_NOT_REACHED() ((void)0)
    239 
    240 #if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
    241 template<typename T>
    242 inline void assertUnused(T& x) { (void)x; }
    243 #define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
    244 #else
    245 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
    246 #endif
    247 
    248 #else
    249 
    250 #define ASSERT(assertion) do \
    251     if (!(assertion)) { \
    252         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
    253         CRASH(); \
    254     } \
    255 while (0)
    256 
    257 #define ASSERT_NOT_REACHED() do { \
    258     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
    259     CRASH(); \
    260 } while (0)
    261 
    262 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
    263 
    264 #endif
    265 
    266 /* ASSERT_WITH_MESSAGE */
    267 
    268 #if COMPILER(MSVC7_OR_LOWER)
    269 #define ASSERT_WITH_MESSAGE(assertion) ((void)0)
    270 #elif COMPILER(WINSCW)
    271 #define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
    272 #elif ASSERT_MSG_DISABLED
    273 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
    274 #else
    275 #define ASSERT_WITH_MESSAGE(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 
    284 /* ASSERT_ARG */
    285 
    286 #if ASSERT_ARG_DISABLED
    287 
    288 #define ASSERT_ARG(argName, assertion) ((void)0)
    289 
    290 #else
    291 
    292 #define ASSERT_ARG(argName, assertion) do \
    293     if (!(assertion)) { \
    294         WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
    295         CRASH(); \
    296     } \
    297 while (0)
    298 
    299 #endif
    300 
    301 /* COMPILE_ASSERT */
    302 #ifndef COMPILE_ASSERT
    303 #define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
    304 #endif
    305 
    306 /* FATAL */
    307 
    308 #if COMPILER(MSVC7_OR_LOWER)
    309 #define FATAL() ((void)0)
    310 #elif COMPILER(WINSCW)
    311 #define FATAL(arg...) ((void)0)
    312 #elif FATAL_DISABLED
    313 #define FATAL(...) ((void)0)
    314 #else
    315 #define FATAL(...) do { \
    316     WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
    317     CRASH(); \
    318 } while (0)
    319 #endif
    320 
    321 /* LOG_ERROR */
    322 
    323 #if COMPILER(MSVC7_OR_LOWER)
    324 #define LOG_ERROR() ((void)0)
    325 #elif COMPILER(WINSCW)
    326 #define LOG_ERROR(arg...)  ((void)0)
    327 #elif ERROR_DISABLED
    328 #define LOG_ERROR(...) ((void)0)
    329 #else
    330 #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
    331 #endif
    332 
    333 /* LOG */
    334 
    335 #if COMPILER(MSVC7_OR_LOWER)
    336 #define LOG() ((void)0)
    337 #elif COMPILER(WINSCW)
    338 #define LOG(arg...) ((void)0)
    339 #elif LOG_DISABLED
    340 #define LOG(channel, ...) ((void)0)
    341 #else
    342 #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
    343 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
    344 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
    345 #endif
    346 
    347 /* LOG_VERBOSE */
    348 
    349 #if COMPILER(MSVC7_OR_LOWER)
    350 #define LOG_VERBOSE(channel) ((void)0)
    351 #elif COMPILER(WINSCW)
    352 #define LOG_VERBOSE(channel, arg...) ((void)0)
    353 #elif LOG_DISABLED
    354 #define LOG_VERBOSE(channel, ...) ((void)0)
    355 #else
    356 #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
    357 #endif
    358 
    359 #endif /* WTF_Assertions_h */
    360