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