Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: Source/WTF/wtf/Assertions.cpp

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007-2009 Torch Mobile, Inc.
4 * Copyright (C) 2011 University of Szeged. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 // The vprintf_stderr_common function triggers this error in the Mac build.
29 // Feel free to remove this pragma if this file builds on Mac.
30 // According to http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Diagnostic-Pragmas.h tml#Diagnostic-Pragmas
31 // we need to place this directive before any data or functions are defined.
32 #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
33
34 #include "config.h"
35 #include "Assertions.h"
36
37 #include "Compiler.h"
38 #include "OwnArrayPtr.h"
39
40 #include <stdio.h>
41 #include <stdarg.h>
42 #include <string.h>
43
44 #if HAVE(SIGNAL_H)
45 #include <signal.h>
46 #endif
47
48 #if USE(CF)
49 #include <CoreFoundation/CFString.h>
50 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
51 #define WTF_USE_APPLE_SYSTEM_LOG 1
52 #include <asl.h>
53 #endif
54 #endif // USE(CF)
55
56 #if COMPILER(MSVC) && !OS(WINCE)
57 #include <crtdbg.h>
58 #endif
59
60 #if OS(WINDOWS)
61 #include <windows.h>
62 #endif
63
64 #if (OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))) && !OS(ANDROID)
65 #include <cxxabi.h>
66 #include <dlfcn.h>
67 #include <execinfo.h>
68 #endif
69
70 #if OS(ANDROID)
71 #include "android/log.h"
72 #endif
73
74 extern "C" {
75
76 WTF_ATTRIBUTE_PRINTF(1, 0)
77 static void vprintf_stderr_common(const char* format, va_list args)
78 {
79 #if USE(CF) && !OS(WINDOWS)
80 if (strstr(format, "%@")) {
81 CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFString EncodingUTF8);
82
83 #if COMPILER(CLANG)
84 #pragma clang diagnostic push
85 #pragma clang diagnostic ignored "-Wformat-nonliteral"
86 #endif
87 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFor mat, args);
88 #if COMPILER(CLANG)
89 #pragma clang diagnostic pop
90 #endif
91 CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str ), kCFStringEncodingUTF8);
92 char* buffer = (char*)malloc(length + 1);
93
94 CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8);
95
96 #if USE(APPLE_SYSTEM_LOG)
97 asl_log(0, 0, ASL_LEVEL_NOTICE, "%s", buffer);
98 #endif
99 fputs(buffer, stderr);
100
101 free(buffer);
102 CFRelease(str);
103 CFRelease(cfFormat);
104 return;
105 }
106
107 #if USE(APPLE_SYSTEM_LOG)
108 va_list copyOfArgs;
109 va_copy(copyOfArgs, args);
110 asl_vlog(0, 0, ASL_LEVEL_NOTICE, format, copyOfArgs);
111 va_end(copyOfArgs);
112 #endif
113
114 // Fall through to write to stderr in the same manner as other platforms.
115
116 #elif OS(ANDROID)
117 __android_log_vprint(ANDROID_LOG_WARN, "WebKit", format, args);
118 #elif HAVE(ISDEBUGGERPRESENT)
119 if (IsDebuggerPresent()) {
120 size_t size = 1024;
121
122 do {
123 char* buffer = (char*)malloc(size);
124
125 if (buffer == NULL)
126 break;
127
128 if (_vsnprintf(buffer, size, format, args) != -1) {
129 #if OS(WINCE)
130 // WinCE only supports wide chars
131 wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t));
132 if (wideBuffer == NULL)
133 break;
134 for (unsigned int i = 0; i < size; ++i) {
135 if (!(wideBuffer[i] = buffer[i]))
136 break;
137 }
138 OutputDebugStringW(wideBuffer);
139 free(wideBuffer);
140 #else
141 OutputDebugStringA(buffer);
142 #endif
143 free(buffer);
144 break;
145 }
146
147 free(buffer);
148 size *= 2;
149 } while (size > 1024);
150 }
151 #endif
152 vfprintf(stderr, format, args);
153 }
154
155 #if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0))
156 #pragma GCC diagnostic push
157 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
158 #endif
159
160 static void vprintf_stderr_with_prefix(const char* prefix, const char* format, v a_list args)
161 {
162 size_t prefixLength = strlen(prefix);
163 size_t formatLength = strlen(format);
164 OwnArrayPtr<char> formatWithPrefix = adoptArrayPtr(new char[prefixLength + f ormatLength + 1]);
165 memcpy(formatWithPrefix.get(), prefix, prefixLength);
166 memcpy(formatWithPrefix.get() + prefixLength, format, formatLength);
167 formatWithPrefix[prefixLength + formatLength] = 0;
168
169 vprintf_stderr_common(formatWithPrefix.get(), args);
170 }
171
172 static void vprintf_stderr_with_trailing_newline(const char* format, va_list arg s)
173 {
174 size_t formatLength = strlen(format);
175 if (formatLength && format[formatLength - 1] == '\n') {
176 vprintf_stderr_common(format, args);
177 return;
178 }
179
180 OwnArrayPtr<char> formatWithNewline = adoptArrayPtr(new char[formatLength + 2]);
181 memcpy(formatWithNewline.get(), format, formatLength);
182 formatWithNewline[formatLength] = '\n';
183 formatWithNewline[formatLength + 1] = 0;
184
185 vprintf_stderr_common(formatWithNewline.get(), args);
186 }
187
188 #if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0))
189 #pragma GCC diagnostic pop
190 #endif
191
192 WTF_ATTRIBUTE_PRINTF(1, 2)
193 static void printf_stderr_common(const char* format, ...)
194 {
195 va_list args;
196 va_start(args, format);
197 vprintf_stderr_common(format, args);
198 va_end(args);
199 }
200
201 static void printCallSite(const char* file, int line, const char* function)
202 {
203 #if OS(WINDOWS) && !OS(WINCE) && defined(_DEBUG)
204 _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function);
205 #else
206 // By using this format, which matches the format used by MSVC for compiler errors, developers
207 // using Visual Studio can double-click the file/line number in the Output W indow to have the
208 // editor navigate to that line of code. It seems fine for other developers, too.
209 printf_stderr_common("%s(%d) : %s\n", file, line, function);
210 #endif
211 }
212
213 void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion)
214 {
215 if (assertion)
216 printf_stderr_common("ASSERTION FAILED: %s\n", assertion);
217 else
218 printf_stderr_common("SHOULD NEVER BE REACHED\n");
219 printCallSite(file, line, function);
220 }
221
222 void WTFReportAssertionFailureWithMessage(const char* file, int line, const char * function, const char* assertion, const char* format, ...)
223 {
224 va_list args;
225 va_start(args, format);
226 vprintf_stderr_with_prefix("ASSERTION FAILED: ", format, args);
227 va_end(args);
228 printf_stderr_common("\n%s\n", assertion);
229 printCallSite(file, line, function);
230 }
231
232 void WTFReportArgumentAssertionFailure(const char* file, int line, const char* f unction, const char* argName, const char* assertion)
233 {
234 printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion);
235 printCallSite(file, line, function);
236 }
237
238 void WTFGetBacktrace(void** stack, int* size)
239 {
240 #if (OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))) && !OS(ANDROID)
241 *size = backtrace(stack, *size);
242 #elif OS(WINDOWS) && !OS(WINCE)
243 // The CaptureStackBackTrace function is available in XP, but it is not defi ned
244 // in the Windows Server 2003 R2 Platform SDK. So, we'll grab the function
245 // through GetProcAddress.
246 typedef WORD (NTAPI* RtlCaptureStackBackTraceFunc)(DWORD, DWORD, PVOID*, PDW ORD);
247 HMODULE kernel32 = ::GetModuleHandleW(L"Kernel32.dll");
248 if (!kernel32) {
249 *size = 0;
250 return;
251 }
252 RtlCaptureStackBackTraceFunc captureStackBackTraceFunc = reinterpret_cast<Rt lCaptureStackBackTraceFunc>(
253 ::GetProcAddress(kernel32, "RtlCaptureStackBackTrace"));
254 if (captureStackBackTraceFunc)
255 *size = captureStackBackTraceFunc(0, *size, stack, 0);
256 else
257 *size = 0;
258 #else
259 *size = 0;
260 #endif
261 }
262
263 void WTFReportBacktrace()
264 {
265 static const int framesToShow = 31;
266 static const int framesToSkip = 2;
267 void* samples[framesToShow + framesToSkip];
268 int frames = framesToShow + framesToSkip;
269
270 WTFGetBacktrace(samples, &frames);
271 WTFPrintBacktrace(samples + framesToSkip, frames - framesToSkip);
272 }
273
274 #if OS(DARWIN) || (OS(LINUX) && !OS(ANDROID))
275 #define WTF_USE_DLADDR 1
276 #endif
277
278 void WTFPrintBacktrace(void** stack, int size)
279 {
280 #if USE(BACKTRACE_SYMBOLS)
281 char** symbols = backtrace_symbols(stack, size);
282 if (!symbols)
283 return;
284 #endif
285
286 for (int i = 0; i < size; ++i) {
287 const char* mangledName = 0;
288 char* cxaDemangled = 0;
289 #if USE(BACKTRACE_SYMBOLS)
290 mangledName = symbols[i];
291 #elif USE(DLADDR)
292 Dl_info info;
293 if (dladdr(stack[i], &info) && info.dli_sname)
294 mangledName = info.dli_sname;
295 if (mangledName)
296 cxaDemangled = abi::__cxa_demangle(mangledName, 0, 0, 0);
297 #endif
298 const int frameNumber = i + 1;
299 if (mangledName || cxaDemangled)
300 printf_stderr_common("%-3d %p %s\n", frameNumber, stack[i], cxaDeman gled ? cxaDemangled : mangledName);
301 else
302 printf_stderr_common("%-3d %p\n", frameNumber, stack[i]);
303 free(cxaDemangled);
304 }
305
306 #if USE(BACKTRACE_SYMBOLS)
307 free(symbols);
308 #endif
309 }
310
311 #undef WTF_USE_BACKTRACE_SYMBOLS
312 #undef WTF_USE_DLADDR
313
314 static WTFCrashHookFunction globalHook = 0;
315
316 void WTFSetCrashHook(WTFCrashHookFunction function)
317 {
318 globalHook = function;
319 }
320
321 void WTFInvokeCrashHook()
322 {
323 if (globalHook)
324 globalHook();
325 }
326
327 #if HAVE(SIGNAL_H)
328 static NO_RETURN void dumpBacktraceSignalHandler(int sig)
329 {
330 WTFReportBacktrace();
331 exit(128 + sig);
332 }
333
334 static void installSignalHandlersForFatalErrors(void (*handler)(int))
335 {
336 signal(SIGILL, handler); // 4: illegal instruction (not reset when caught ).
337 signal(SIGTRAP, handler); // 5: trace trap (not reset when caught).
338 signal(SIGFPE, handler); // 8: floating point exception.
339 signal(SIGBUS, handler); // 10: bus error.
340 signal(SIGSEGV, handler); // 11: segmentation violation.
341 signal(SIGSYS, handler); // 12: bad argument to system call.
342 signal(SIGPIPE, handler); // 13: write on a pipe with no reader.
343 signal(SIGXCPU, handler); // 24: exceeded CPU time limit.
344 signal(SIGXFSZ, handler); // 25: exceeded file size limit.
345 }
346
347 static void resetSignalHandlersForFatalErrors()
348 {
349 installSignalHandlersForFatalErrors(SIG_DFL);
350 }
351 #endif
352
353 void WTFInstallReportBacktraceOnCrashHook()
354 {
355 #if HAVE(SIGNAL_H)
356 // Needed otherwise we are going to dump the stack trace twice
357 // in case we hit an assertion.
358 WTFSetCrashHook(&resetSignalHandlersForFatalErrors);
359 installSignalHandlersForFatalErrors(&dumpBacktraceSignalHandler);
360 #endif
361 }
362
363 void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
364 {
365 va_list args;
366 va_start(args, format);
367 vprintf_stderr_with_prefix("FATAL ERROR: ", format, args);
368 va_end(args);
369 printf_stderr_common("\n");
370 printCallSite(file, line, function);
371 }
372
373 void WTFReportError(const char* file, int line, const char* function, const char * format, ...)
374 {
375 va_list args;
376 va_start(args, format);
377 vprintf_stderr_with_prefix("ERROR: ", format, args);
378 va_end(args);
379 printf_stderr_common("\n");
380 printCallSite(file, line, function);
381 }
382
383 void WTFLog(WTFLogChannel* channel, const char* format, ...)
384 {
385 if (channel->state != WTFLogChannelOn)
386 return;
387
388 va_list args;
389 va_start(args, format);
390 vprintf_stderr_with_trailing_newline(format, args);
391 va_end(args);
392 }
393
394 void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann el* channel, const char* format, ...)
395 {
396 if (channel->state != WTFLogChannelOn)
397 return;
398
399 va_list args;
400 va_start(args, format);
401 vprintf_stderr_with_trailing_newline(format, args);
402 va_end(args);
403
404 printCallSite(file, line, function);
405 }
406
407 void WTFLogAlways(const char* format, ...)
408 {
409 va_list args;
410 va_start(args, format);
411 vprintf_stderr_with_trailing_newline(format, args);
412 va_end(args);
413 }
414
415 } // extern "C"
OLDNEW
« no previous file with comments | « Source/WTF/wtf/Assertions.h ('k') | Source/WTF/wtf/Atomics.h » ('j') | Source/config.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698