OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. |
3 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
4 * Copyright (C) 2011 University of Szeged. All rights reserved. | 4 * Copyright (C) 2011 University of Szeged. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 #if OS(MACOSX) || (OS(LINUX) && !defined(__UCLIBC__)) | 63 #if OS(MACOSX) || (OS(LINUX) && !defined(__UCLIBC__)) |
64 #include <cxxabi.h> | 64 #include <cxxabi.h> |
65 #include <dlfcn.h> | 65 #include <dlfcn.h> |
66 #include <execinfo.h> | 66 #include <execinfo.h> |
67 #endif | 67 #endif |
68 | 68 |
69 #if OS(ANDROID) | 69 #if OS(ANDROID) |
70 #include <android/log.h> | 70 #include <android/log.h> |
71 #endif | 71 #endif |
72 | 72 |
73 // TODO(tkent): These function should be in anonymous namespace. | |
74 void WTFGetBacktrace(void** stack, int* size); | |
75 void WTFPrintBacktrace(void** stack, int size); | |
76 | |
77 PRINTF_FORMAT(1, 0) | 73 PRINTF_FORMAT(1, 0) |
78 static void vprintf_stderr_common(const char* format, va_list args) { | 74 static void vprintf_stderr_common(const char* format, va_list args) { |
79 #if OS(MACOSX) && USE(APPLE_SYSTEM_LOG) | 75 #if OS(MACOSX) && USE(APPLE_SYSTEM_LOG) |
80 va_list copyOfArgs; | 76 va_list copyOfArgs; |
81 va_copy(copyOfArgs, args); | 77 va_copy(copyOfArgs, args); |
82 asl_vlog(0, 0, ASL_LEVEL_NOTICE, format, copyOfArgs); | 78 asl_vlog(0, 0, ASL_LEVEL_NOTICE, format, copyOfArgs); |
83 va_end(copyOfArgs); | 79 va_end(copyOfArgs); |
84 #elif OS(ANDROID) | 80 #elif OS(ANDROID) |
85 __android_log_vprint(ANDROID_LOG_WARN, "WebKit", format, args); | 81 __android_log_vprint(ANDROID_LOG_WARN, "WebKit", format, args); |
86 #elif OS(WIN) | 82 #elif OS(WIN) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 formatWithNewline[formatLength] = '\n'; | 121 formatWithNewline[formatLength] = '\n'; |
126 formatWithNewline[formatLength + 1] = 0; | 122 formatWithNewline[formatLength + 1] = 0; |
127 | 123 |
128 vprintf_stderr_common(formatWithNewline.get(), args); | 124 vprintf_stderr_common(formatWithNewline.get(), args); |
129 } | 125 } |
130 | 126 |
131 #if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0)) | 127 #if COMPILER(CLANG) || (COMPILER(GCC) && GCC_VERSION_AT_LEAST(4, 6, 0)) |
132 #pragma GCC diagnostic pop | 128 #pragma GCC diagnostic pop |
133 #endif | 129 #endif |
134 | 130 |
135 PRINTF_FORMAT(1, 2) | |
136 static void printf_stderr_common(const char* format, ...) { | |
137 va_list args; | |
138 va_start(args, format); | |
139 vprintf_stderr_common(format, args); | |
140 va_end(args); | |
141 } | |
142 | |
143 static void printCallSite(const char* file, int line, const char* function) { | |
144 #if OS(WIN) && defined(_DEBUG) | |
145 _CrtDbgReport(_CRT_WARN, file, line, nullptr, "%s\n", function); | |
146 #else | |
147 // By using this format, which matches the format used by MSVC for compiler | |
148 // errors, developers using Visual Studio can double-click the file/line | |
149 // number in the Output Window to have the editor navigate to that line of | |
150 // code. It seems fine for other developers, too. | |
151 printf_stderr_common("%s(%d) : %s\n", file, line, function); | |
152 #endif | |
153 } | |
154 | |
155 void WTFReportAssertionFailure(const char* file, | |
156 int line, | |
157 const char* function, | |
158 const char* assertion) { | |
159 if (assertion) | |
160 printf_stderr_common("ASSERTION FAILED: %s\n", assertion); | |
161 else | |
162 printf_stderr_common("SHOULD NEVER BE REACHED\n"); | |
163 printCallSite(file, line, function); | |
164 } | |
165 | |
166 void WTFGetBacktrace(void** stack, int* size) { | |
167 #if OS(MACOSX) || (OS(LINUX) && !defined(__UCLIBC__)) | |
168 *size = backtrace(stack, *size); | |
169 #elif OS(WIN) | |
170 // The CaptureStackBackTrace function is available in XP, but it is not | |
171 // defined in the Windows Server 2003 R2 Platform SDK. So, we'll grab the | |
172 // function through GetProcAddress. | |
173 typedef WORD(NTAPI * RtlCaptureStackBackTraceFunc)(DWORD, DWORD, PVOID*, | |
174 PDWORD); | |
175 HMODULE kernel32 = ::GetModuleHandleW(L"Kernel32.dll"); | |
176 if (!kernel32) { | |
177 *size = 0; | |
178 return; | |
179 } | |
180 RtlCaptureStackBackTraceFunc captureStackBackTraceFunc = | |
181 reinterpret_cast<RtlCaptureStackBackTraceFunc>( | |
182 ::GetProcAddress(kernel32, "RtlCaptureStackBackTrace")); | |
183 if (captureStackBackTraceFunc) | |
184 *size = captureStackBackTraceFunc(0, *size, stack, 0); | |
185 else | |
186 *size = 0; | |
187 #else | |
188 *size = 0; | |
189 #endif | |
190 } | |
191 | |
192 void WTFReportBacktrace(int framesToShow) { | |
193 static const int framesToSkip = 2; | |
194 // Use alloca to allocate on the stack since this function is used in OOM | |
195 // situations. | |
196 void** samples = static_cast<void**>( | |
197 alloca((framesToShow + framesToSkip) * sizeof(void*))); | |
198 int frames = framesToShow + framesToSkip; | |
199 | |
200 WTFGetBacktrace(samples, &frames); | |
201 WTFPrintBacktrace(samples + framesToSkip, frames - framesToSkip); | |
202 } | |
203 | |
204 namespace { | 131 namespace { |
205 | 132 |
206 class FrameToNameScope { | 133 class FrameToNameScope { |
207 public: | 134 public: |
208 explicit FrameToNameScope(void*); | 135 explicit FrameToNameScope(void*); |
209 ~FrameToNameScope(); | 136 ~FrameToNameScope(); |
210 const char* nullableName() { return m_name; } | 137 const char* nullableName() { return m_name; } |
211 | 138 |
212 private: | 139 private: |
213 const char* m_name; | 140 const char* m_name; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 new ThreadSpecific<ScopedLogger*>); | 242 new ThreadSpecific<ScopedLogger*>); |
316 return *ref; | 243 return *ref; |
317 } | 244 } |
318 | 245 |
319 ScopedLogger::PrintFunctionPtr ScopedLogger::m_printFunc = | 246 ScopedLogger::PrintFunctionPtr ScopedLogger::m_printFunc = |
320 vprintf_stderr_common; | 247 vprintf_stderr_common; |
321 | 248 |
322 } // namespace WTF | 249 } // namespace WTF |
323 #endif // !LOG_DISABLED | 250 #endif // !LOG_DISABLED |
324 | 251 |
325 void WTFPrintBacktrace(void** stack, int size) { | |
326 for (int i = 0; i < size; ++i) { | |
327 FrameToNameScope frameToName(stack[i]); | |
328 const int frameNumber = i + 1; | |
329 if (frameToName.nullableName()) | |
330 printf_stderr_common("%-3d %p %s\n", frameNumber, stack[i], | |
331 frameToName.nullableName()); | |
332 else | |
333 printf_stderr_common("%-3d %p\n", frameNumber, stack[i]); | |
334 } | |
335 } | |
336 | |
337 void WTFLogAlways(const char* format, ...) { | 252 void WTFLogAlways(const char* format, ...) { |
338 va_list args; | 253 va_list args; |
339 va_start(args, format); | 254 va_start(args, format); |
340 vprintf_stderr_with_trailing_newline(format, args); | 255 vprintf_stderr_with_trailing_newline(format, args); |
341 va_end(args); | 256 va_end(args); |
342 } | 257 } |
OLD | NEW |