diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/Assertions.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/Assertions.h')
-rw-r--r-- | Source/WTF/wtf/Assertions.h | 232 |
1 files changed, 140 insertions, 92 deletions
diff --git a/Source/WTF/wtf/Assertions.h b/Source/WTF/wtf/Assertions.h index 4d968b865..3158c1039 100644 --- a/Source/WTF/wtf/Assertions.h +++ b/Source/WTF/wtf/Assertions.h @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,20 +26,30 @@ #ifndef WTF_Assertions_h #define WTF_Assertions_h +#include <wtf/Platform.h> + /* no namespaces because this file has to be includable from C and Objective-C Note, this file uses many GCC extensions, but it should be compatible with C, Objective C, C++, and Objective C++. - For non-debug builds, everything is disabled by default. - Defining any of the symbols explicitly prevents this from having any effect. + For non-debug builds, everything is disabled by default except for "always + on" logging. Defining any of the symbols explicitly prevents this from + having any effect. */ +#undef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS #include <inttypes.h> #include <stdarg.h> +#include <stdbool.h> #include <stddef.h> -#include <wtf/Platform.h> +#include <wtf/ExportMacros.h> + +#if USE(OS_LOG) +#include <os/log.h> +#endif #ifdef NDEBUG /* Disable ASSERT* macros in release mode. */ @@ -76,16 +86,23 @@ #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT #endif -#if COMPILER(GCC) +#ifndef RELEASE_LOG_DISABLED +#define RELEASE_LOG_DISABLED !(USE(OS_LOG)) +#endif + +#if COMPILER(GCC_OR_CLANG) #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__ #else #define WTF_PRETTY_FUNCTION __FUNCTION__ #endif +#if COMPILER(MINGW) +/* By default MinGW emits warnings when C99 format attributes are used, even if __USE_MINGW_ANSI_STDIO is defined */ +#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(gnu_printf, formatStringArgument, extraArguments))) +#elif COMPILER(GCC_OR_CLANG) && !defined(__OBJC__) /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include the attribute when being used from Objective-C code in case it decides to use %@. */ -#if COMPILER(GCC) && !defined(__OBJC__) #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments))) #else #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) @@ -112,19 +129,43 @@ extern "C" { Signals are ignored by the crash reporter on OS X so we must do better. */ -#if COMPILER(CLANG) +#if COMPILER(GCC_OR_CLANG) || COMPILER(MSVC) #define NO_RETURN_DUE_TO_CRASH NO_RETURN #else #define NO_RETURN_DUE_TO_CRASH #endif -typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState; +typedef enum { WTFLogChannelOff, WTFLogChannelOn, WTFLogChannelOnWithAccumulation } WTFLogChannelState; typedef struct { WTFLogChannelState state; const char* name; +#if !RELEASE_LOG_DISABLED + const char* subsystem; + __unsafe_unretained os_log_t osLogChannel; +#endif } WTFLogChannel; +#define LOG_CHANNEL(name) JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, name) +#define LOG_CHANNEL_ADDRESS(name) &LOG_CHANNEL(name), +#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) +#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel + +#define LOG_CHANNEL_WEBKIT_SUBSYSTEM "com.apple.WebKit" + +#define DECLARE_LOG_CHANNEL(name) \ + extern WTFLogChannel LOG_CHANNEL(name); + +#if !defined(DEFINE_LOG_CHANNEL) +#if RELEASE_LOG_DISABLED +#define DEFINE_LOG_CHANNEL(name, subsystem) \ + WTFLogChannel LOG_CHANNEL(name) = { WTFLogChannelOff, #name }; +#else +#define DEFINE_LOG_CHANNEL(name, subsystem) \ + WTFLogChannel LOG_CHANNEL(name) = { WTFLogChannelOff, #name, subsystem, OS_LOG_DEFAULT }; +#endif +#endif + WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion); WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion); @@ -134,7 +175,7 @@ WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTR WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); WTF_EXPORT_PRIVATE void WTFLogAlwaysV(const char* format, va_list); WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2); -WTF_EXPORT_PRIVATE void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2) NO_RETURN_DUE_TO_CRASH; +WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2); WTF_EXPORT_PRIVATE WTFLogChannel* WTFLogChannelByName(WTFLogChannel*[], size_t count, const char*); WTF_EXPORT_PRIVATE void WTFInitializeLogChannelStatesFromString(WTFLogChannel*[], size_t count, const char*); @@ -146,32 +187,42 @@ typedef void (*WTFCrashHookFunction)(); WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction); WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook(); -// Exist for binary compatibility with older Safari. Do not use. -WTF_EXPORT_PRIVATE void WTFInvokeCrashHook(); -#ifdef __cplusplus -} -#endif +WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached(); #ifndef CRASH -#define CRASH() WTFCrash() -#endif -#ifdef __cplusplus -extern "C" { +#if defined(NDEBUG) && OS(DARWIN) +#if CPU(X86_64) || CPU(X86) +#define WTFBreakpointTrap() __asm__ volatile ("int3") +#elif CPU(ARM_THUMB2) +#define WTFBreakpointTrap() __asm__ volatile ("bkpt #0") +#elif CPU(ARM64) +#define WTFBreakpointTrap() __asm__ volatile ("brk #0") +#else +#error "Unsupported CPU". #endif -WTF_EXPORT_PRIVATE void WTFCrash() NO_RETURN_DUE_TO_CRASH; -#ifdef __cplusplus -} + +// Crash with a SIGTRAP i.e EXC_BREAKPOINT. +// We are not using __builtin_trap because it is only guaranteed to abort, but not necessarily +// trigger a SIGTRAP. Instead, we use inline asm to ensure that we trigger the SIGTRAP. +#define CRASH() do { \ + WTFBreakpointTrap(); \ + __builtin_unreachable(); \ +} while (0) +#else +#define CRASH() WTFCrash() #endif +#endif // CRASH + +WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrash(); + #ifndef CRASH_WITH_SECURITY_IMPLICATION #define CRASH_WITH_SECURITY_IMPLICATION() WTFCrashWithSecurityImplication() #endif -#ifdef __cplusplus -extern "C" { -#endif - WTF_EXPORT_PRIVATE void WTFCrashWithSecurityImplication() NO_RETURN_DUE_TO_CRASH; +WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrashWithSecurityImplication(); + #ifdef __cplusplus } #endif @@ -199,14 +250,6 @@ extern "C" { Expressions inside them are evaluated in debug builds only. */ -#if OS(WINCE) -/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */ -#include <windows.h> -#undef min -#undef max -#undef ERROR -#endif - #if OS(WINDOWS) /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */ #undef ASSERT @@ -217,11 +260,12 @@ extern "C" { #define ASSERT(assertion) ((void)0) #define ASSERT_AT(assertion, file, line, function) ((void)0) #define ASSERT_NOT_REACHED() ((void)0) +#define ASSERT_IMPLIES(condition, assertion) ((void)0) #define NO_RETURN_DUE_TO_ASSERT #define ASSERT_UNUSED(variable, assertion) ((void)variable) -#ifdef ADDRESS_SANITIZER +#if ENABLE(SECURITY_ASSERTIONS) #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \ (!(assertion) ? \ (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \ @@ -236,23 +280,32 @@ extern "C" { #else -#define ASSERT(assertion) \ - (!(assertion) ? \ - (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \ - CRASH()) : \ - (void)0) +#define ASSERT(assertion) do { \ + if (!(assertion)) { \ + WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \ + CRASH(); \ + } \ +} while (0) -#define ASSERT_AT(assertion, file, line, function) \ - (!(assertion) ? \ - (WTFReportAssertionFailure(file, line, function, #assertion), \ - CRASH()) : \ - (void)0) +#define ASSERT_AT(assertion, file, line, function) do { \ + if (!(assertion)) { \ + WTFReportAssertionFailure(file, line, function, #assertion); \ + CRASH(); \ + } \ +} while (0) #define ASSERT_NOT_REACHED() do { \ WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ CRASH(); \ } while (0) +#define ASSERT_IMPLIES(condition, assertion) do { \ + if ((condition) && !(assertion)) { \ + WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #condition " => " #assertion); \ + CRASH(); \ + } \ +} while (0) + #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion) #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH @@ -278,12 +331,12 @@ extern "C" { #if ASSERT_MSG_DISABLED #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) #else -#define ASSERT_WITH_MESSAGE(assertion, ...) do \ +#define ASSERT_WITH_MESSAGE(assertion, ...) do { \ if (!(assertion)) { \ WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ CRASH(); \ } \ -while (0) +} while (0) #endif /* ASSERT_WITH_MESSAGE_UNUSED */ @@ -291,12 +344,12 @@ while (0) #if ASSERT_MSG_DISABLED #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable) #else -#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \ +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do { \ if (!(assertion)) { \ WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ CRASH(); \ } \ -while (0) +} while (0) #endif @@ -308,12 +361,12 @@ while (0) #else -#define ASSERT_ARG(argName, assertion) do \ +#define ASSERT_ARG(argName, assertion) do { \ if (!(assertion)) { \ WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \ CRASH(); \ } \ -while (0) +} while (0) #endif @@ -351,9 +404,7 @@ while (0) #if LOG_DISABLED #define LOG(channel, ...) ((void)0) #else -#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) -#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) -#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel +#define LOG(channel, ...) WTFLog(&LOG_CHANNEL(channel), __VA_ARGS__) #endif /* LOG_VERBOSE */ @@ -361,7 +412,39 @@ while (0) #if LOG_DISABLED #define LOG_VERBOSE(channel, ...) ((void)0) #else -#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) +#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &LOG_CHANNEL(channel), __VA_ARGS__) +#endif + +/* RELEASE_LOG */ + +#if RELEASE_LOG_DISABLED +#define RELEASE_LOG( channel, format, ...) ((void)0) +#define RELEASE_LOG_ERROR(channel, format, ...) LOG_ERROR(format, ##__VA_ARGS__) + +#define RELEASE_LOG_IF( isAllowed, channel, format, ...) ((void)0) +#define RELEASE_LOG_ERROR_IF(isAllowed, channel, format, ...) do { if (isAllowed) RELEASE_LOG_ERROR(channel, format, ##__VA_ARGS__); } while (0) +#else +#define RELEASE_LOG( channel, format, ...) os_log( LOG_CHANNEL(channel).osLogChannel, format, ##__VA_ARGS__) +#define RELEASE_LOG_ERROR(channel, format, ...) os_log_error(LOG_CHANNEL(channel).osLogChannel, format, ##__VA_ARGS__) + +#define RELEASE_LOG_IF( isAllowed, channel, format, ...) do { if (isAllowed) RELEASE_LOG( channel, format, ##__VA_ARGS__); } while (0) +#define RELEASE_LOG_ERROR_IF(isAllowed, channel, format, ...) do { if (isAllowed) RELEASE_LOG_ERROR(channel, format, ##__VA_ARGS__); } while (0) +#endif + + +/* RELEASE_ASSERT */ + +#if ASSERT_DISABLED +#define RELEASE_ASSERT(assertion) do { \ + if (UNLIKELY(!(assertion))) \ + CRASH(); \ +} while (0) +#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion) +#define RELEASE_ASSERT_NOT_REACHED() CRASH() +#else +#define RELEASE_ASSERT(assertion) ASSERT(assertion) +#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__) +#define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED() #endif /* UNREACHABLE_FOR_PLATFORM */ @@ -373,47 +456,12 @@ while (0) #pragma clang diagnostic ignored "-Wmissing-noreturn" static inline void UNREACHABLE_FOR_PLATFORM() { - ASSERT_NOT_REACHED(); + RELEASE_ASSERT_NOT_REACHED(); } #pragma clang diagnostic pop #else -#define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED() -#endif - -#if ASSERT_DISABLED -#define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0) -#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion) -#define RELEASE_ASSERT_NOT_REACHED() CRASH() -#else -#define RELEASE_ASSERT(assertion) ASSERT(assertion) -#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__) -#define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED() +#define UNREACHABLE_FOR_PLATFORM() RELEASE_ASSERT_NOT_REACHED() #endif -/* TYPE CAST */ - -#define TYPE_CASTS_BASE(ToClassName, argumentType, argumentName, pointerPredicate, referencePredicate) \ -inline ToClassName* to##ToClassName(argumentType* argumentName) \ -{ \ - ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \ - return static_cast<ToClassName*>(argumentName); \ -} \ -inline const ToClassName* to##ToClassName(const argumentType* argumentName) \ -{ \ - ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \ - return static_cast<const ToClassName*>(argumentName); \ -} \ -inline ToClassName& to##ToClassName(argumentType& argumentName) \ -{ \ - ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \ - return static_cast<ToClassName&>(argumentName); \ -} \ -inline const ToClassName& to##ToClassName(const argumentType& argumentName) \ -{ \ - ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \ - return static_cast<const ToClassName&>(argumentName); \ -} \ -void to##ToClassName(const ToClassName*); \ -void to##ToClassName(const ToClassName&); #endif /* WTF_Assertions_h */ |