2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007-2009 Torch Mobile, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // The vprintf_stderr_common function triggers this error in the Mac build.
28 // Feel free to remove this pragma if this file builds on Mac.
29 // According to http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
30 // we need to place this directive before any data or functions are defined.
31 #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
34 #include "Assertions.h"
41 #include <CoreFoundation/CFString.h>
44 #if COMPILER(MSVC) && !OS(WINCE) && !PLATFORM(BREWMP)
54 #include <wtf/Vector.h>
67 static void printLog(const Vector<char>& buffer)
69 // Each call to DBGPRINTF generates at most 128 bytes of output on the Windows SDK.
70 // On Qualcomm chipset targets, DBGPRINTF() comes out the diag port (though this may change).
71 // The length of each output string is constrained even more than on the Windows SDK.
73 const int printBufferSize = 128;
75 const int printBufferSize = 32;
78 char printBuffer[printBufferSize + 1];
79 printBuffer[printBufferSize] = 0; // to guarantee null termination
81 const char* p = buffer.data();
82 const char* end = buffer.data() + buffer.size();
84 strncpy(printBuffer, p, printBufferSize);
85 dbg_Message(printBuffer, DBG_MSG_LEVEL_HIGH, __FILE__, __LINE__);
92 WTF_ATTRIBUTE_PRINTF(1, 0)
93 static void vprintf_stderr_common(const char* format, va_list args)
96 if (strstr(format, "%@")) {
97 CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
98 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
100 int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
101 char* buffer = (char*)malloc(length + 1);
103 CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8);
105 fputs(buffer, stderr);
112 #elif PLATFORM(BREWMP)
113 // When str is 0, the return value is the number of bytes needed
114 // to accept the result including null termination.
115 int size = vsnprintf(0, 0, format, args);
117 Vector<char> buffer(size);
118 vsnprintf(buffer.data(), size, format, args);
122 #elif HAVE(ISDEBUGGERPRESENT)
123 if (IsDebuggerPresent()) {
127 char* buffer = (char*)malloc(size);
132 if (_vsnprintf(buffer, size, format, args) != -1) {
134 // WinCE only supports wide chars
135 wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t));
136 if (wideBuffer == NULL)
138 for (unsigned int i = 0; i < size; ++i) {
139 if (!(wideBuffer[i] = buffer[i]))
142 OutputDebugStringW(wideBuffer);
145 OutputDebugStringA(buffer);
153 } while (size > 1024);
157 vfprintf(stdout, format, args);
159 vfprintf(stderr, format, args);
163 WTF_ATTRIBUTE_PRINTF(1, 2)
164 static void printf_stderr_common(const char* format, ...)
167 va_start(args, format);
168 vprintf_stderr_common(format, args);
172 static void printCallSite(const char* file, int line, const char* function)
174 #if OS(WINDOWS) && !OS(WINCE) && defined(_DEBUG)
175 _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function);
177 // By using this format, which matches the format used by MSVC for compiler errors, developers
178 // using Visual Studio can double-click the file/line number in the Output Window to have the
179 // editor navigate to that line of code. It seems fine for other developers, too.
180 printf_stderr_common("%s(%d) : %s\n", file, line, function);
184 void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion)
187 printf_stderr_common("ASSERTION FAILED: %s\n", assertion);
189 printf_stderr_common("SHOULD NEVER BE REACHED\n");
190 printCallSite(file, line, function);
193 void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...)
195 printf_stderr_common("ASSERTION FAILED: ");
197 va_start(args, format);
198 vprintf_stderr_common(format, args);
200 printf_stderr_common("\n%s\n", assertion);
201 printCallSite(file, line, function);
204 void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion)
206 printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion);
207 printCallSite(file, line, function);
210 void WTFReportBacktrace()
213 static const int maxFrames = 32;
214 void* samples[maxFrames];
215 int frames = backtrace(samples, maxFrames);
217 for (int i = 1; i < frames; ++i) {
218 void* pointer = samples[i];
220 // Try to get a symbol name from the dynamic linker.
222 if (dladdr(pointer, &info) && info.dli_sname) {
223 const char* mangledName = info.dli_sname;
225 // Assume c++ & try to demangle the name.
226 char* demangledName = abi::__cxa_demangle(mangledName, 0, 0, 0);
228 fprintf(stderr, "%-3d %s\n", i, demangledName);
231 fprintf(stderr, "%-3d %s\n", i, mangledName);
233 fprintf(stderr, "%-3d %p\n", i, pointer);
238 void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
240 printf_stderr_common("FATAL ERROR: ");
242 va_start(args, format);
243 vprintf_stderr_common(format, args);
245 printf_stderr_common("\n");
246 printCallSite(file, line, function);
249 void WTFReportError(const char* file, int line, const char* function, const char* format, ...)
251 printf_stderr_common("ERROR: ");
253 va_start(args, format);
254 vprintf_stderr_common(format, args);
256 printf_stderr_common("\n");
257 printCallSite(file, line, function);
260 void WTFLog(WTFLogChannel* channel, const char* format, ...)
262 if (channel->state != WTFLogChannelOn)
266 va_start(args, format);
267 vprintf_stderr_common(format, args);
270 size_t formatLength = strlen(format);
271 if (formatLength && format[formatLength - 1] != '\n')
272 printf_stderr_common("\n");
275 void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...)
277 if (channel->state != WTFLogChannelOn)
281 va_start(args, format);
282 vprintf_stderr_common(format, args);
285 size_t formatLength = strlen(format);
286 if (formatLength && format[formatLength - 1] != '\n')
287 printf_stderr_common("\n");
289 printCallSite(file, line, function);