summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/Assertions.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/Assertions.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WTF/wtf/Assertions.h')
-rw-r--r--Source/WTF/wtf/Assertions.h232
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 */