< prev index next >

src/share/vm/utilities/debug.cpp

Print this page
rev 7424 : improve secondary signal handling


 291       VMError err(message);
 292       err.report_java_out_of_memory();
 293     }
 294   }
 295 }
 296 
 297 static bool error_reported = false;
 298 
 299 // call this when the VM is dying--it might loosen some asserts
 300 void set_error_reported() {
 301   error_reported = true;
 302 }
 303 
 304 bool is_error_reported() {
 305     return error_reported;
 306 }
 307 
 308 #ifndef PRODUCT
 309 #include <signal.h>
 310 













































































 311 void test_error_handler() {
 312   uintx test_num = ErrorHandlerTest;
 313   if (test_num == 0) return;



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


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




 291       VMError err(message);
 292       err.report_java_out_of_memory();
 293     }
 294   }
 295 }
 296 
 297 static bool error_reported = false;
 298 
 299 // call this when the VM is dying--it might loosen some asserts
 300 void set_error_reported() {
 301   error_reported = true;
 302 }
 303 
 304 bool is_error_reported() {
 305     return error_reported;
 306 }
 307 
 308 #ifndef PRODUCT
 309 #include <signal.h>
 310 
 311 typedef void (*voidfun_t)();
 312 // Crash with an authentic sigill at a known PC.
 313 static void crash_with_sigill() {
 314   bool rc = false;
 315   const size_t size = os::vm_page_size();
 316   static void* pc = NULL;
 317 
 318   // prepare a "blob" with an illegal instruction sequence which 
 319   // we then execute. Have to use os::reserve_memory to be able to
 320   // make the memory executable.
 321   if (!pc) {
 322     void* p = os::reserve_memory(size, NULL, 0);
 323     if (p) {
 324       bool rc = os::commit_memory((char*)p, size, true);
 325       if (rc) {
 326         if (get_illegal_instruction_sequence((uint8_t*)p)) {
 327           pc = p;
 328         }
 329       }
 330     }
 331   }
 332  
 333   // Fallback: if there is no implementation for get_illegal_instruction_sequence
 334   // for the current platform, just do a raise(SIGILL). Raising a signal is 
 335   // different from triggering it naturaly (e.g. raised synchronous signals can
 336   // be blocked) but for the test purposes it is better than nothing.
 337   if (pc == NULL) {
 338     tty->print_cr("will raise a SIGILL");
 339     tty->flush();
 340     raise(SIGILL);
 341     ShouldNotReachHere();
 342   } 
 343 
 344   tty->print_cr("will jump to PC " PTR_FORMAT 
 345     ", which should cause a SIGILL.", pc);
 346   tty->flush();
 347 
 348   volatile voidfun_t g_voidfun = NULL;
 349 
 350 #if defined(IA64) || defined(PPC64) 
 351   // on ia64 and on ppc we have function descriptors. 
 352   struct { void* p1; void* p2; } fundes = 
 353     { pc, pc }; 
 354   void* p = (void*)(&fundes);
 355   g_voidfun = (voidfun_t) (p);
 356 #else
 357   g_voidfun = (voidfun_t)pc;
 358 #endif
 359 
 360   g_voidfun(); // boom.
 361 
 362 } // end: crash_with_sigill
 363 
 364 // crash with sigsegv at non-null address.
 365 static void crash_with_segfault() {
 366 
 367   char* const crash_addr = (char*) get_segfault_address();
 368 
 369   tty->print_cr("will access address " PTR_FORMAT 
 370     ", which should cause a SIGSEGV.", crash_addr);
 371   tty->flush();
 372 
 373   *crash_addr = 'X';
 374 
 375 } // end: crash_with_segfault
 376 
 377 // returns an address which is guaranteed to generate a SIGSEGV on read,
 378 // for test purposes, which is not NULL and contains bits in every word
 379 void* get_segfault_address() {
 380   return (void*)
 381 #ifdef _LP64
 382     0xABC0000000000ABCULL;
 383 #else
 384     0x00000ABC;
 385 #endif
 386 }
 387 
 388 void test_error_handler() {
 389   controlled_crash(ErrorHandlerTest);
 390 }
 391 
 392 void controlled_crash(int how) {
 393   if (how == 0) return;
 394 
 395   // If asserts are disabled, use the corresponding guarantee instead.
 396   NOT_DEBUG(if (how <= 2) how += 2);

 397 
 398   const char* const str = "hello";
 399   const size_t      num = (size_t)os::vm_page_size();
 400 
 401   const char* const eol = os::line_separator();
 402   const char* const msg = "this message should be truncated during formatting";
 403   char * const dataPtr = NULL;  // bad data pointer
 404   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 405 
 406   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 407   switch (how) {
 408     case  1: assert(str == NULL, "expected null");
 409     case  2: assert(num == 1023 && *str == 'X',
 410                     err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 411     case  3: guarantee(str == NULL, "expected null");
 412     case  4: guarantee(num == 1023 && *str == 'X',
 413                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 414     case  5: fatal("expected null");
 415     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 416     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 417                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 418                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 419                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 420                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 421                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 422     case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
 423     case  9: ShouldNotCallThis();
 424     case 10: ShouldNotReachHere();
 425     case 11: Unimplemented();
 426     // There's no guarantee the bad data pointer will crash us
 427     // so "break" out to the ShouldNotReachHere().
 428     case 12: *dataPtr = '\0'; break;
 429     // There's no guarantee the bad function pointer will crash us
 430     // so "break" out to the ShouldNotReachHere().
 431     case 13: (*funcPtr)(); break;
 432     case 14: crash_with_segfault(); break;
 433     case 15: crash_with_sigill(); break;
 434 
 435     default: tty->print_cr("ERROR: %d: unexpected test_num value.", how);
 436   }
 437   ShouldNotReachHere();
 438 }
 439 #endif // !PRODUCT
 440 
 441 // ------ helper functions for debugging go here ------------
 442 
 443 // All debug entries should be wrapped with a stack allocated
 444 // Command object. It makes sure a resource mark is set and
 445 // flushes the logfile to prevent file sharing problems.
 446 
 447 class Command : public StackObj {
 448  private:
 449   ResourceMark rm;
 450   ResetNoHandleMark rnhm;
 451   HandleMark   hm;
 452   bool debug_save;
 453  public:
 454   static int level;
 455   Command(const char* str) {


< prev index next >