]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/Assertions.cpp
7027143f4748aa1d0cf0b46693f6f8babdc2f6a5
[apple/javascriptcore.git] / wtf / Assertions.cpp
1 /*
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007-2009 Torch Mobile, Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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.
25 */
26
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"
32
33 #include "config.h"
34 #include "Assertions.h"
35
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <string.h>
39
40 #include <CoreFoundation/CFString.h>
41
42 #if COMPILER(MSVC) && !OS(WINCE) && !PLATFORM(BREWMP)
43 #ifndef WINVER
44 #define WINVER 0x0500
45 #endif
46 #ifndef _WIN32_WINNT
47 #define _WIN32_WINNT 0x0500
48 #endif
49 #include <crtdbg.h>
50 #endif
51
52 #if OS(WINDOWS)
53 #include <windows.h>
54 #endif
55
56 #if PLATFORM(BREWMP)
57 #include <AEEdbg.h>
58 #include <wtf/Vector.h>
59 #endif
60
61 #if PLATFORM(MAC)
62 #include <cxxabi.h>
63 #include <dlfcn.h>
64 #include <execinfo.h>
65 #endif
66
67 extern "C" {
68
69 #if PLATFORM(BREWMP)
70
71 static void printLog(const Vector<char>& buffer)
72 {
73 // Each call to DBGPRINTF generates at most 128 bytes of output on the Windows SDK.
74 // On Qualcomm chipset targets, DBGPRINTF() comes out the diag port (though this may change).
75 // The length of each output string is constrained even more than on the Windows SDK.
76 #if COMPILER(MSVC)
77 const int printBufferSize = 128;
78 #else
79 const int printBufferSize = 32;
80 #endif
81
82 char printBuffer[printBufferSize + 1];
83 printBuffer[printBufferSize] = 0; // to guarantee null termination
84
85 const char* p = buffer.data();
86 const char* end = buffer.data() + buffer.size();
87 while (p < end) {
88 strncpy(printBuffer, p, printBufferSize);
89 dbg_Message(printBuffer, DBG_MSG_LEVEL_HIGH, __FILE__, __LINE__);
90 p += printBufferSize;
91 }
92 }
93
94 #endif
95
96 WTF_ATTRIBUTE_PRINTF(1, 0)
97 static void vprintf_stderr_common(const char* format, va_list args)
98 {
99 if (strstr(format, "%@")) {
100 CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
101 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
102
103 int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
104 char* buffer = (char*)malloc(length + 1);
105
106 CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8);
107
108 fputs(buffer, stderr);
109
110 free(buffer);
111 CFRelease(str);
112 CFRelease(cfFormat);
113 return;
114 }
115 #if OS(SYMBIAN)
116 vfprintf(stdout, format, args);
117 #else
118 vfprintf(stderr, format, args);
119 #endif
120 }
121
122 WTF_ATTRIBUTE_PRINTF(1, 2)
123 static void printf_stderr_common(const char* format, ...)
124 {
125 va_list args;
126 va_start(args, format);
127 vprintf_stderr_common(format, args);
128 va_end(args);
129 }
130
131 static void printCallSite(const char* file, int line, const char* function)
132 {
133 #if OS(WINDOWS) && !OS(WINCE) && defined(_DEBUG)
134 _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function);
135 #else
136 // By using this format, which matches the format used by MSVC for compiler errors, developers
137 // using Visual Studio can double-click the file/line number in the Output Window to have the
138 // editor navigate to that line of code. It seems fine for other developers, too.
139 printf_stderr_common("%s(%d) : %s\n", file, line, function);
140 #endif
141 }
142
143 void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion)
144 {
145 if (assertion)
146 printf_stderr_common("ASSERTION FAILED: %s\n", assertion);
147 else
148 printf_stderr_common("SHOULD NEVER BE REACHED\n");
149 printCallSite(file, line, function);
150 }
151
152 void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...)
153 {
154 printf_stderr_common("ASSERTION FAILED: ");
155 va_list args;
156 va_start(args, format);
157 vprintf_stderr_common(format, args);
158 va_end(args);
159 printf_stderr_common("\n%s\n", assertion);
160 printCallSite(file, line, function);
161 }
162
163 void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion)
164 {
165 printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion);
166 printCallSite(file, line, function);
167 }
168
169 void WTFReportBacktrace()
170 {
171 #if PLATFORM(MAC)
172 static const int maxFrames = 32;
173 void* samples[maxFrames];
174 int frames = backtrace(samples, maxFrames);
175
176 for (int i = 1; i < frames; ++i) {
177 void* pointer = samples[i];
178
179 // Try to get a symbol name from the dynamic linker.
180 Dl_info info;
181 if (dladdr(pointer, &info) && info.dli_sname) {
182 const char* mangledName = info.dli_sname;
183
184 // Assume c++ & try to demangle the name.
185 char* demangledName = abi::__cxa_demangle(mangledName, 0, 0, 0);
186 if (demangledName) {
187 fprintf(stderr, "%-3d %s\n", i, demangledName);
188 free(demangledName);
189 } else
190 fprintf(stderr, "%-3d %s\n", i, mangledName);
191 } else
192 fprintf(stderr, "%-3d %p\n", i, pointer);
193 }
194 #endif
195 }
196
197 void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
198 {
199 printf_stderr_common("FATAL ERROR: ");
200 va_list args;
201 va_start(args, format);
202 vprintf_stderr_common(format, args);
203 va_end(args);
204 printf_stderr_common("\n");
205 printCallSite(file, line, function);
206 }
207
208 void WTFReportError(const char* file, int line, const char* function, const char* format, ...)
209 {
210 printf_stderr_common("ERROR: ");
211 va_list args;
212 va_start(args, format);
213 vprintf_stderr_common(format, args);
214 va_end(args);
215 printf_stderr_common("\n");
216 printCallSite(file, line, function);
217 }
218
219 void WTFLog(WTFLogChannel* channel, const char* format, ...)
220 {
221 if (channel->state != WTFLogChannelOn)
222 return;
223
224 va_list args;
225 va_start(args, format);
226 vprintf_stderr_common(format, args);
227 va_end(args);
228
229 size_t formatLength = strlen(format);
230 if (formatLength && format[formatLength - 1] != '\n')
231 printf_stderr_common("\n");
232 }
233
234 void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...)
235 {
236 if (channel->state != WTFLogChannelOn)
237 return;
238
239 va_list args;
240 va_start(args, format);
241 vprintf_stderr_common(format, args);
242 va_end(args);
243
244 size_t formatLength = strlen(format);
245 if (formatLength && format[formatLength - 1] != '\n')
246 printf_stderr_common("\n");
247
248 printCallSite(file, line, function);
249 }
250
251 } // extern "C"