Mercurial > hg > truffle
comparison src/share/vm/utilities/debug.cpp @ 1490:f03d0a26bf83
6888954: argument formatting for assert() and friends
Reviewed-by: kvn, twisti, apetrusenko, never, dcubed
author | jcoomes |
---|---|
date | Thu, 22 Apr 2010 13:23:15 -0700 |
parents | 148e5441d916 |
children | c18cbe5936b8 |
comparison
equal
deleted
inserted
replaced
1489:cff162798819 | 1490:f03d0a26bf83 |
---|---|
70 static int last_line_no = -1; | 70 static int last_line_no = -1; |
71 | 71 |
72 // assert/guarantee/... may happen very early during VM initialization. | 72 // assert/guarantee/... may happen very early during VM initialization. |
73 // Don't rely on anything that is initialized by Threads::create_vm(). For | 73 // Don't rely on anything that is initialized by Threads::create_vm(). For |
74 // example, don't use tty. | 74 // example, don't use tty. |
75 bool assert_is_suppressed(const char* file_name, int line_no) { | 75 bool error_is_suppressed(const char* file_name, int line_no) { |
76 // The following 1-element cache requires that passed-in | 76 // The following 1-element cache requires that passed-in |
77 // file names are always only constant literals. | 77 // file names are always only constant literals. |
78 if (file_name == last_file_name && line_no == last_line_no) return true; | 78 if (file_name == last_file_name && line_no == last_line_no) return true; |
79 | 79 |
80 int file_name_len = (int)strlen(file_name); | 80 int file_name_len = (int)strlen(file_name); |
161 #undef is_token_break | 161 #undef is_token_break |
162 | 162 |
163 #else | 163 #else |
164 | 164 |
165 // Place-holder for non-existent suppression check: | 165 // Place-holder for non-existent suppression check: |
166 #define assert_is_suppressed(file_name, line_no) (false) | 166 #define error_is_suppressed(file_name, line_no) (false) |
167 | 167 |
168 #endif //PRODUCT | 168 #endif //PRODUCT |
169 | 169 |
170 void report_assertion_failure(const char* file_name, int line_no, const char* message) { | 170 void report_vm_error(const char* file, int line, const char* error_msg, |
171 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | 171 const char* detail_msg) |
172 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); | 172 { |
173 if (Debugging || error_is_suppressed(file, line)) return; | |
174 Thread* const thread = ThreadLocalStorage::get_thread_slow(); | |
175 VMError err(thread, file, line, error_msg, detail_msg); | |
173 err.report_and_die(); | 176 err.report_and_die(); |
174 } | 177 } |
175 | 178 |
176 void report_fatal(const char* file_name, int line_no, const char* message) { | 179 void report_fatal(const char* file, int line, const char* message) |
177 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | 180 { |
178 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); | 181 report_vm_error(file, line, "fatal error", message); |
179 err.report_and_die(); | 182 } |
180 } | |
181 | |
182 void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...) { | |
183 char buffer[256]; | |
184 va_list ap; | |
185 va_start(ap, format); | |
186 jio_vsnprintf(buffer, sizeof(buffer), format, ap); | |
187 va_end(ap); | |
188 report_fatal(file_name, line_no, buffer); | |
189 } | |
190 | |
191 | 183 |
192 // Used by report_vm_out_of_memory to detect recursion. | 184 // Used by report_vm_out_of_memory to detect recursion. |
193 static jint _exiting_out_of_mem = 0; | 185 static jint _exiting_out_of_mem = 0; |
194 | 186 |
195 // Just passing the flow to VMError to handle error | 187 void report_vm_out_of_memory(const char* file, int line, size_t size, |
196 void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message) { | 188 const char* message) { |
197 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | 189 if (Debugging || error_is_suppressed(file, line)) return; |
198 | 190 |
199 // We try to gather additional information for the first out of memory | 191 // We try to gather additional information for the first out of memory |
200 // error only; gathering additional data might cause an allocation and a | 192 // error only; gathering additional data might cause an allocation and a |
201 // recursive out_of_memory condition. | 193 // recursive out_of_memory condition. |
202 | 194 |
204 // If we succeed in changing the value, we're the first one in. | 196 // If we succeed in changing the value, we're the first one in. |
205 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; | 197 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; |
206 | 198 |
207 if (first_time_here) { | 199 if (first_time_here) { |
208 Thread* thread = ThreadLocalStorage::get_thread_slow(); | 200 Thread* thread = ThreadLocalStorage::get_thread_slow(); |
209 VMError(thread, size, message, file_name, line_no).report_and_die(); | 201 VMError(thread, file, line, size, message).report_and_die(); |
210 } | 202 } |
211 | 203 |
212 // Dump core and abort | 204 // Dump core and abort |
213 vm_abort(true); | 205 vm_abort(true); |
214 } | 206 } |
215 | 207 |
216 void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) { | 208 void report_should_not_call(const char* file, int line) { |
217 char buffer[256]; | 209 report_vm_error(file, line, "ShouldNotCall()"); |
218 va_list ap; | 210 } |
219 va_start(ap, format); | 211 |
220 jio_vsnprintf(buffer, sizeof(buffer), format, ap); | 212 void report_should_not_reach_here(const char* file, int line) { |
221 va_end(ap); | 213 report_vm_error(file, line, "ShouldNotReachHere()"); |
222 report_vm_out_of_memory(file_name, line_no, size, buffer); | 214 } |
223 } | 215 |
224 | 216 void report_unimplemented(const char* file, int line) { |
225 void report_should_not_call(const char* file_name, int line_no) { | 217 report_vm_error(file, line, "Unimplemented()"); |
226 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | 218 } |
227 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no); | 219 |
228 err.report_and_die(); | 220 void report_untested(const char* file, int line, const char* message) { |
229 } | |
230 | |
231 | |
232 void report_should_not_reach_here(const char* file_name, int line_no) { | |
233 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | |
234 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no); | |
235 err.report_and_die(); | |
236 } | |
237 | |
238 | |
239 void report_unimplemented(const char* file_name, int line_no) { | |
240 if (Debugging || assert_is_suppressed(file_name, line_no)) return; | |
241 VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no); | |
242 err.report_and_die(); | |
243 } | |
244 | |
245 | |
246 void report_untested(const char* file_name, int line_no, const char* msg) { | |
247 #ifndef PRODUCT | 221 #ifndef PRODUCT |
248 warning("Untested: %s in %s: %d\n", msg, file_name, line_no); | 222 warning("Untested: %s in %s: %d\n", message, file, line); |
249 #endif // PRODUCT | 223 #endif // PRODUCT |
250 } | 224 } |
251 | 225 |
252 void report_java_out_of_memory(const char* message) { | 226 void report_java_out_of_memory(const char* message) { |
253 static jint out_of_memory_reported = 0; | 227 static jint out_of_memory_reported = 0; |
281 } | 255 } |
282 | 256 |
283 bool is_error_reported() { | 257 bool is_error_reported() { |
284 return error_reported; | 258 return error_reported; |
285 } | 259 } |
260 | |
261 #ifndef PRODUCT | |
262 #include <signal.h> | |
263 | |
264 void test_error_handler(size_t test_num) | |
265 { | |
266 if (test_num == 0) return; | |
267 | |
268 // If asserts are disabled, use the corresponding guarantee instead. | |
269 size_t n = test_num; | |
270 NOT_DEBUG(if (n <= 2) n += 2); | |
271 | |
272 const char* const str = "hello"; | |
273 const size_t num = (size_t)os::vm_page_size(); | |
274 | |
275 const char* const eol = os::line_separator(); | |
276 const char* const msg = "this message should be truncated during formatting"; | |
277 | |
278 // Keep this in sync with test/runtime/6888954/vmerrors.sh. | |
279 switch (n) { | |
280 case 1: assert(str == NULL, "expected null"); | |
281 case 2: assert(num == 1023 && *str == 'X', | |
282 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); | |
283 case 3: guarantee(str == NULL, "expected null"); | |
284 case 4: guarantee(num == 1023 && *str == 'X', | |
285 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); | |
286 case 5: fatal("expected null"); | |
287 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); | |
288 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# " | |
289 "%s%s# %s%s# %s%s# %s%s# %s%s# " | |
290 "%s%s# %s%s# %s%s# %s%s# %s", | |
291 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, | |
292 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, | |
293 msg, eol, msg, eol, msg, eol, msg, eol, msg)); | |
294 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate"); | |
295 case 9: ShouldNotCallThis(); | |
296 case 10: ShouldNotReachHere(); | |
297 case 11: Unimplemented(); | |
298 // This is last because it does not generate an hs_err* file on Windows. | |
299 case 12: os::signal_raise(SIGSEGV); | |
300 | |
301 default: ShouldNotReachHere(); | |
302 } | |
303 } | |
304 #endif // #ifndef PRODUCT | |
286 | 305 |
287 // ------ helper functions for debugging go here ------------ | 306 // ------ helper functions for debugging go here ------------ |
288 | 307 |
289 #ifndef PRODUCT | 308 #ifndef PRODUCT |
290 // All debug entries should be wrapped with a stack allocated | 309 // All debug entries should be wrapped with a stack allocated |