< prev index next >

src/share/vm/utilities/debug.cpp

Print this page
rev 7758 : 8065895 Synchronous signals during error reporting may terminate or hang VM process
Reviewed-by: dholmes,gziemski
Contributed-by: stuefe


 299       VMError err(message);
 300       err.report_java_out_of_memory();
 301     }
 302   }
 303 }
 304 
 305 static bool error_reported = false;
 306 
 307 // call this when the VM is dying--it might loosen some asserts
 308 void set_error_reported() {
 309   error_reported = true;
 310 }
 311 
 312 bool is_error_reported() {
 313     return error_reported;
 314 }
 315 
 316 #ifndef PRODUCT
 317 #include <signal.h>
 318 
































 319 void test_error_handler() {
 320   uintx test_num = ErrorHandlerTest;
 321   if (test_num == 0) return;



 322 
 323   // If asserts are disabled, use the corresponding guarantee instead.
 324   size_t n = test_num;
 325   NOT_DEBUG(if (n <= 2) n += 2);
 326 
 327   const char* const str = "hello";
 328   const size_t      num = (size_t)os::vm_page_size();
 329 
 330   const char* const eol = os::line_separator();
 331   const char* const msg = "this message should be truncated during formatting";
 332   char * const dataPtr = NULL;  // bad data pointer
 333   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 334 
 335   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 336   switch (n) {
 337     case  1: vmassert(str == NULL, "expected null");
 338     case  2: vmassert(num == 1023 && *str == 'X',
 339                       err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 340     case  3: guarantee(str == NULL, "expected null");
 341     case  4: guarantee(num == 1023 && *str == 'X',
 342                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 343     case  5: fatal("expected null");
 344     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 345     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 346                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 347                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 348                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 349                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 350                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 351     case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
 352     case  9: ShouldNotCallThis();
 353     case 10: ShouldNotReachHere();
 354     case 11: Unimplemented();
 355     // There's no guarantee the bad data pointer will crash us
 356     // so "break" out to the ShouldNotReachHere().
 357     case 12: *dataPtr = '\0'; break;
 358     // There's no guarantee the bad function pointer will crash us
 359     // so "break" out to the ShouldNotReachHere().
 360     case 13: (*funcPtr)(); break;


 361 
 362     default: tty->print_cr("ERROR: %d: unexpected test_num value.", n);
 363   }
 364   ShouldNotReachHere();
 365 }
 366 #endif // !PRODUCT
 367 
 368 // ------ helper functions for debugging go here ------------
 369 
 370 // All debug entries should be wrapped with a stack allocated
 371 // Command object. It makes sure a resource mark is set and
 372 // flushes the logfile to prevent file sharing problems.
 373 
 374 class Command : public StackObj {
 375  private:
 376   ResourceMark rm;
 377   ResetNoHandleMark rnhm;
 378   HandleMark   hm;
 379   bool debug_save;
 380  public:
 381   static int level;
 382   Command(const char* str) {




 299       VMError err(message);
 300       err.report_java_out_of_memory();
 301     }
 302   }
 303 }
 304 
 305 static bool error_reported = false;
 306 
 307 // call this when the VM is dying--it might loosen some asserts
 308 void set_error_reported() {
 309   error_reported = true;
 310 }
 311 
 312 bool is_error_reported() {
 313     return error_reported;
 314 }
 315 
 316 #ifndef PRODUCT
 317 #include <signal.h>
 318 
 319 typedef void (*voidfun_t)();
 320 // Crash with an authentic sigfpe
 321 static void crash_with_sigfpe() {
 322   // generate a native synchronous SIGFPE where possible;
 323   // if that did not cause a signal (e.g. on ppc), just
 324   // raise the signal.
 325   volatile int x = 0;
 326   volatile int y = 1/x;
 327 #ifndef _WIN32
 328   raise(SIGFPE);
 329 #endif
 330 } // end: crash_with_sigfpe
 331 
 332 // crash with sigsegv at non-null address.
 333 static void crash_with_segfault() {
 334 
 335   char* const crash_addr = (char*) get_segfault_address();
 336   *crash_addr = 'X';
 337 
 338 } // end: crash_with_segfault
 339 
 340 // returns an address which is guaranteed to generate a SIGSEGV on read,
 341 // for test purposes, which is not NULL and contains bits in every word
 342 void* get_segfault_address() {
 343   return (void*)
 344 #ifdef _LP64
 345     0xABC0000000000ABCULL;
 346 #else
 347     0x00000ABC;
 348 #endif
 349 }
 350 
 351 void test_error_handler() {
 352   controlled_crash(ErrorHandlerTest);
 353 }
 354 
 355 void controlled_crash(int how) {
 356   if (how == 0) return;
 357 
 358   // If asserts are disabled, use the corresponding guarantee instead.
 359   NOT_DEBUG(if (how <= 2) how += 2);

 360 
 361   const char* const str = "hello";
 362   const size_t      num = (size_t)os::vm_page_size();
 363 
 364   const char* const eol = os::line_separator();
 365   const char* const msg = "this message should be truncated during formatting";
 366   char * const dataPtr = NULL;  // bad data pointer
 367   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 368 
 369   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 370   switch (how) {
 371     case  1: vmassert(str == NULL, "expected null");
 372     case  2: vmassert(num == 1023 && *str == 'X',
 373                       err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 374     case  3: guarantee(str == NULL, "expected null");
 375     case  4: guarantee(num == 1023 && *str == 'X',
 376                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 377     case  5: fatal("expected null");
 378     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 379     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 380                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 381                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 382                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 383                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 384                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 385     case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
 386     case  9: ShouldNotCallThis();
 387     case 10: ShouldNotReachHere();
 388     case 11: Unimplemented();
 389     // There's no guarantee the bad data pointer will crash us
 390     // so "break" out to the ShouldNotReachHere().
 391     case 12: *dataPtr = '\0'; break;
 392     // There's no guarantee the bad function pointer will crash us
 393     // so "break" out to the ShouldNotReachHere().
 394     case 13: (*funcPtr)(); break;
 395     case 14: crash_with_segfault(); break;
 396     case 15: crash_with_sigfpe(); break;
 397 
 398     default: tty->print_cr("ERROR: %d: unexpected test_num value.", how);
 399   }
 400   ShouldNotReachHere();
 401 }
 402 #endif // !PRODUCT
 403 
 404 // ------ helper functions for debugging go here ------------
 405 
 406 // All debug entries should be wrapped with a stack allocated
 407 // Command object. It makes sure a resource mark is set and
 408 // flushes the logfile to prevent file sharing problems.
 409 
 410 class Command : public StackObj {
 411  private:
 412   ResourceMark rm;
 413   ResetNoHandleMark rnhm;
 414   HandleMark   hm;
 415   bool debug_save;
 416  public:
 417   static int level;
 418   Command(const char* str) {


< prev index next >