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.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/Assertions.cpp')
-rw-r--r-- | Source/WTF/wtf/Assertions.cpp | 246 |
1 files changed, 174 insertions, 72 deletions
diff --git a/Source/WTF/wtf/Assertions.cpp b/Source/WTF/wtf/Assertions.cpp index a37030245..8613df5de 100644 --- a/Source/WTF/wtf/Assertions.cpp +++ b/Source/WTF/wtf/Assertions.cpp @@ -12,10 +12,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 @@ -35,27 +35,31 @@ #include "Assertions.h" #include "Compiler.h" +#include <mutex> +#include <stdio.h> +#include <string.h> +#include <wtf/Lock.h> +#include <wtf/Locker.h> +#include <wtf/LoggingAccumulator.h> #include <wtf/StdLibExtras.h> #include <wtf/StringExtras.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> #include <wtf/text/WTFString.h> -#include <stdio.h> -#include <string.h> - #if HAVE(SIGNAL_H) #include <signal.h> #endif #if USE(CF) #include <CoreFoundation/CFString.h> -#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 -#define WTF_USE_APPLE_SYSTEM_LOG 1 +#if PLATFORM(COCOA) +#define USE_APPLE_SYSTEM_LOG 1 #include <asl.h> #endif #endif // USE(CF) -#if COMPILER(MSVC) && !OS(WINCE) +#if COMPILER(MSVC) #include <crtdbg.h> #endif @@ -63,7 +67,12 @@ #include <windows.h> #endif -#if OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__)) +#if OS(DARWIN) +#include <sys/sysctl.h> +#include <unistd.h> +#endif + +#if OS(DARWIN) || (OS(LINUX) && defined(__GLIBC__) && !defined(__UCLIBC__)) #include <cxxabi.h> #include <dlfcn.h> #include <execinfo.h> @@ -71,6 +80,17 @@ extern "C" { +static void logToStderr(const char* buffer) +{ +#if USE(APPLE_SYSTEM_LOG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + asl_log(0, 0, ASL_LEVEL_NOTICE, "%s", buffer); +#pragma clang diagnostic pop +#endif + fputs(buffer, stderr); +} + WTF_ATTRIBUTE_PRINTF(1, 0) static void vprintf_stderr_common(const char* format, va_list args) { @@ -91,10 +111,7 @@ static void vprintf_stderr_common(const char* format, va_list args) CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8); -#if USE(APPLE_SYSTEM_LOG) - asl_log(0, 0, ASL_LEVEL_NOTICE, "%s", buffer); -#endif - fputs(buffer, stderr); + logToStderr(buffer); free(buffer); CFRelease(str); @@ -103,10 +120,13 @@ static void vprintf_stderr_common(const char* format, va_list args) } #if USE(APPLE_SYSTEM_LOG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" va_list copyOfArgs; va_copy(copyOfArgs, args); asl_vlog(0, 0, ASL_LEVEL_NOTICE, format, copyOfArgs); va_end(copyOfArgs); +#pragma clang diagnostic pop #endif // Fall through to write to stderr in the same manner as other platforms. @@ -121,21 +141,8 @@ static void vprintf_stderr_common(const char* format, va_list args) if (buffer == NULL) break; - if (_vsnprintf(buffer, size, format, args) != -1) { -#if OS(WINCE) - // WinCE only supports wide chars - wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t)); - if (wideBuffer == NULL) - break; - for (unsigned int i = 0; i < size; ++i) { - if (!(wideBuffer[i] = buffer[i])) - break; - } - OutputDebugStringW(wideBuffer); - free(wideBuffer); -#else + if (vsnprintf(buffer, size, format, args) != -1) { OutputDebugStringA(buffer); -#endif free(buffer); break; } @@ -148,7 +155,7 @@ static void vprintf_stderr_common(const char* format, va_list args) vfprintf(stderr, format, args); } -#if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0)) +#if COMPILER(GCC_OR_CLANG) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif @@ -181,7 +188,7 @@ static void vprintf_stderr_with_trailing_newline(const char* format, va_list arg vprintf_stderr_common(formatWithNewline.get(), args); } -#if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0)) +#if COMPILER(GCC_OR_CLANG) #pragma GCC diagnostic pop #endif @@ -196,7 +203,7 @@ static void printf_stderr_common(const char* format, ...) static void printCallSite(const char* file, int line, const char* function) { -#if OS(WINDOWS) && !OS(WINCE) && defined(_DEBUG) +#if OS(WINDOWS) && defined(_DEBUG) _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function); #else // By using this format, which matches the format used by MSVC for compiler errors, developers @@ -233,24 +240,10 @@ void WTFReportArgumentAssertionFailure(const char* file, int line, const char* f void WTFGetBacktrace(void** stack, int* size) { -#if OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__)) +#if OS(DARWIN) || (OS(LINUX) && defined(__GLIBC__) && !defined(__UCLIBC__)) *size = backtrace(stack, *size); -#elif OS(WINDOWS) && !OS(WINCE) - // The CaptureStackBackTrace function is available in XP, but it is not defined - // in the Windows Server 2003 R2 Platform SDK. So, we'll grab the function - // through GetProcAddress. - typedef WORD (NTAPI* RtlCaptureStackBackTraceFunc)(DWORD, DWORD, PVOID*, PDWORD); - HMODULE kernel32 = ::GetModuleHandleW(L"Kernel32.dll"); - if (!kernel32) { - *size = 0; - return; - } - RtlCaptureStackBackTraceFunc captureStackBackTraceFunc = reinterpret_cast<RtlCaptureStackBackTraceFunc>( - ::GetProcAddress(kernel32, "RtlCaptureStackBackTrace")); - if (captureStackBackTraceFunc) - *size = captureStackBackTraceFunc(0, *size, stack, 0); - else - *size = 0; +#elif OS(WINDOWS) + *size = RtlCaptureStackBackTrace(0, *size, stack, 0); #else *size = 0; #endif @@ -270,10 +263,10 @@ void WTFReportBacktrace() #if OS(DARWIN) || OS(LINUX) # if PLATFORM(GTK) # if defined(__GLIBC__) && !defined(__UCLIBC__) -# define WTF_USE_BACKTRACE_SYMBOLS 1 +# define USE_BACKTRACE_SYMBOLS 1 # endif # else -# define WTF_USE_DLADDR 1 +# define USE_DLADDR 1 # endif #endif @@ -310,8 +303,8 @@ void WTFPrintBacktrace(void** stack, int size) #endif } -#undef WTF_USE_BACKTRACE_SYMBOLS -#undef WTF_USE_DLADDR +#undef USE_BACKTRACE_SYMBOLS +#undef USE_DLADDR static WTFCrashHookFunction globalHook = 0; @@ -320,10 +313,7 @@ void WTFSetCrashHook(WTFCrashHookFunction function) globalHook = function; } -void WTFInvokeCrashHook() -{ -} - +#if !defined(NDEBUG) || !OS(DARWIN) void WTFCrash() { if (globalHook) @@ -332,25 +322,25 @@ void WTFCrash() WTFReportBacktrace(); *(int *)(uintptr_t)0xbbadbeef = 0; // More reliable, but doesn't say BBADBEEF. -#if COMPILER(CLANG) +#if COMPILER(GCC_OR_CLANG) __builtin_trap(); #else ((void(*)())0)(); #endif } - +#else +// We need to keep WTFCrash() around (even on non-debug OS(DARWIN) builds) as a workaround +// for presently shipping (circa early 2016) SafariForWebKitDevelopment binaries which still +// expects to link to it. +void WTFCrash() +{ + CRASH(); +} +#endif // !defined(NDEBUG) || !OS(DARWIN) + void WTFCrashWithSecurityImplication() { - if (globalHook) - globalHook(); - WTFReportBacktrace(); - *(int *)(uintptr_t)0xfbadbeef = 0; - // More reliable, but doesn't say fbadbeef. -#if COMPILER(CLANG) - __builtin_trap(); -#else - ((void(*)())0)(); -#endif + CRASH(); } #if HAVE(SIGNAL_H) @@ -389,6 +379,20 @@ void WTFInstallReportBacktraceOnCrashHook() #endif } +bool WTFIsDebuggerAttached() +{ +#if OS(DARWIN) + struct kinfo_proc info; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; + size_t size = sizeof(info); + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &info, &size, nullptr, 0) == -1) + return false; + return info.kp_proc.p_flag & P_TRACED; +#else + return false; +#endif +} + void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) { va_list args; @@ -409,15 +413,83 @@ void WTFReportError(const char* file, int line, const char* function, const char printCallSite(file, line, function); } +class WTFLoggingAccumulator { +public: + void accumulate(const String&); + void resetAccumulatedLogs(); + String getAndResetAccumulatedLogs(); + +private: + Lock accumulatorLock; + StringBuilder loggingAccumulator; +}; + +void WTFLoggingAccumulator::accumulate(const String& log) +{ + Locker<Lock> locker(accumulatorLock); + loggingAccumulator.append(log); +} + +void WTFLoggingAccumulator::resetAccumulatedLogs() +{ + Locker<Lock> locker(accumulatorLock); + loggingAccumulator.clear(); +} + +String WTFLoggingAccumulator::getAndResetAccumulatedLogs() +{ + Locker<Lock> locker(accumulatorLock); + String result = loggingAccumulator.toString(); + loggingAccumulator.clear(); + return result; +} + +static WTFLoggingAccumulator& loggingAccumulator() +{ + static WTFLoggingAccumulator* accumulator; + static std::once_flag initializeAccumulatorOnce; + std::call_once(initializeAccumulatorOnce, [] { + accumulator = new WTFLoggingAccumulator; + }); + + return *accumulator; +} + void WTFLog(WTFLogChannel* channel, const char* format, ...) { - if (channel->state != WTFLogChannelOn) + if (channel->state == WTFLogChannelOff) return; + if (channel->state == WTFLogChannelOn) { + va_list args; + va_start(args, format); + vprintf_stderr_with_trailing_newline(format, args); + va_end(args); + return; + } + + ASSERT(channel->state == WTFLogChannelOnWithAccumulation); + va_list args; va_start(args, format); - vprintf_stderr_with_trailing_newline(format, args); + +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +#endif + String loggingString = String::format(format, args); +#if COMPILER(CLANG) +#pragma clang diagnostic pop +#endif + va_end(args); + + if (!loggingString.endsWith('\n')) + loggingString.append('\n'); + + loggingAccumulator().accumulate(loggingString); + + logToStderr(loggingString.utf8().data()); } void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) @@ -427,7 +499,16 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann va_list args; va_start(args, format); - vprintf_stderr_with_trailing_newline(format, args); + +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +#endif + WTFLog(channel, format, args); +#if COMPILER(CLANG) +#pragma clang diagnostic pop +#endif + va_end(args); printCallSite(file, line, function); @@ -452,7 +533,7 @@ void WTFLogAlwaysAndCrash(const char* format, ...) va_start(args, format); WTFLogAlwaysV(format, args); va_end(args); - WTFCrash(); + CRASH(); } WTFLogChannel* WTFLogChannelByName(WTFLogChannel* channels[], size_t count, const char* name) @@ -474,6 +555,13 @@ static void setStateOfAllChannels(WTFLogChannel* channels[], size_t channelCount void WTFInitializeLogChannelStatesFromString(WTFLogChannel* channels[], size_t count, const char* logLevel) { +#if !RELEASE_LOG_DISABLED + for (size_t i = 0; i < count; ++i) { + WTFLogChannel* channel = channels[i]; + channel->osLogChannel = os_log_create(channel->subsystem, channel->name); + } +#endif + String logLevelString = logLevel; Vector<String> components; logLevelString.split(',', components); @@ -487,7 +575,7 @@ void WTFInitializeLogChannelStatesFromString(WTFLogChannel* channels[], size_t c component = component.substring(1); } - if (equalIgnoringCase(component, "all")) { + if (equalLettersIgnoringASCIICase(component, "all")) { setStateOfAllChannels(channels, count, logChannelState); continue; } @@ -500,3 +588,17 @@ void WTFInitializeLogChannelStatesFromString(WTFLogChannel* channels[], size_t c } } // extern "C" + +namespace WTF { + +void resetAccumulatedLogs() +{ + loggingAccumulator().resetAccumulatedLogs(); +} + +String getAndResetAccumulatedLogs() +{ + return loggingAccumulator().getAndResetAccumulatedLogs(); +} + +} // namespace WTF |