< prev index next >

src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp

Print this page
rev 7968 : 8074552:  SafeFetch32 and SafeFetchN do not work in error handling
Summary: handle SafeFetch faults in secondary signal handlers
Reviewed-by: dholmes
Contributed-by: Thomas Stuefe


 380 #endif
 381 
 382       else if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
 383         if (TraceTraps) {
 384           tty->print_raw_cr("Fix SIGFPE handler, trying divide by zero handler.");
 385         }
 386         stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
 387         goto run_stub;
 388       }
 389 
 390       else if (sig == SIGBUS) {
 391         // BugId 4454115: A read from a MappedByteBuffer can fault here if the
 392         // underlying file has been truncated. Do not crash the VM in such a case.
 393         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
 394         nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
 395         if (nm != NULL && nm->has_unsafe_access()) {
 396           // We don't really need a stub here! Just set the pending exeption and
 397           // continue at the next instruction after the faulting read. Returning
 398           // garbage from this read is ok.
 399           thread->set_pending_unsafe_access_error();
 400           uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4;
 401           return 1;
 402         }
 403       }
 404     }
 405 
 406     else { // thread->thread_state() != _thread_in_Java
 407       // Detect CPU features. This is only done at the very start of the VM. Later, the
 408       // VM_Version::is_determine_features_test_running() flag should be false.
 409 
 410       if (sig == SIGILL && VM_Version::is_determine_features_test_running()) {
 411         // SIGILL must be caused by VM_Version::determine_features().
 412         *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL,
 413                         // flushing of icache is not necessary.
 414         stub = pc + 4;  // continue with next instruction.
 415         goto run_stub;
 416       }
 417       else if (thread->thread_state() == _thread_in_vm &&
 418                sig == SIGBUS && thread->doing_unsafe_access()) {
 419         // We don't really need a stub here! Just set the pending exeption and
 420         // continue at the next instruction after the faulting read. Returning
 421         // garbage from this read is ok.
 422         thread->set_pending_unsafe_access_error();
 423         uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4;
 424         return 1;
 425       }
 426     }
 427 
 428     // Check to see if we caught the safepoint code in the
 429     // process of write protecting the memory serialization page.
 430     // It write enables the page immediately after protecting it
 431     // so we can just return to retry the write.
 432     if ((sig == SIGSEGV) &&
 433         os::is_memory_serialize_page(thread, addr)) {
 434       // Synchronization problem in the pseudo memory barrier code (bug id 6546278)
 435       // Block current thread until the memory serialize page permission restored.
 436       os::block_on_serialize_page_trap();
 437       return true;
 438     }
 439   }
 440 
 441 run_stub:
 442 
 443   // One of the above code blocks ininitalized the stub, so we want to
 444   // delegate control to that stub.
 445   if (stub != NULL) {
 446     // Save all thread context in case we need to restore it.
 447     if (thread != NULL) thread->set_saved_exception_pc(pc);
 448     uc->uc_mcontext.jmp_context.iar = (unsigned long)stub;
 449     return 1;
 450   }
 451 
 452 run_chained_handler:
 453 
 454   // signal-chaining
 455   if (os::Aix::chained_handler(sig, info, ucVoid)) {
 456     return 1;
 457   }
 458   if (!abort_if_unrecognized) {
 459     // caller wants another chance, so give it to him
 460     return 0;
 461   }
 462 
 463 report_and_die:
 464 
 465   // Use sigthreadmask instead of sigprocmask on AIX and unmask current signal.
 466   sigset_t newset;
 467   sigemptyset(&newset);
 468   sigaddset(&newset, sig);




 380 #endif
 381 
 382       else if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
 383         if (TraceTraps) {
 384           tty->print_raw_cr("Fix SIGFPE handler, trying divide by zero handler.");
 385         }
 386         stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
 387         goto run_stub;
 388       }
 389 
 390       else if (sig == SIGBUS) {
 391         // BugId 4454115: A read from a MappedByteBuffer can fault here if the
 392         // underlying file has been truncated. Do not crash the VM in such a case.
 393         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
 394         nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
 395         if (nm != NULL && nm->has_unsafe_access()) {
 396           // We don't really need a stub here! Just set the pending exeption and
 397           // continue at the next instruction after the faulting read. Returning
 398           // garbage from this read is ok.
 399           thread->set_pending_unsafe_access_error();
 400           os::Aix::ucontext_set_pc(uc, pc + 4);
 401           return 1;
 402         }
 403       }
 404     }
 405 
 406     else { // thread->thread_state() != _thread_in_Java
 407       // Detect CPU features. This is only done at the very start of the VM. Later, the
 408       // VM_Version::is_determine_features_test_running() flag should be false.
 409 
 410       if (sig == SIGILL && VM_Version::is_determine_features_test_running()) {
 411         // SIGILL must be caused by VM_Version::determine_features().
 412         *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL,
 413                         // flushing of icache is not necessary.
 414         stub = pc + 4;  // continue with next instruction.
 415         goto run_stub;
 416       }
 417       else if (thread->thread_state() == _thread_in_vm &&
 418                sig == SIGBUS && thread->doing_unsafe_access()) {
 419         // We don't really need a stub here! Just set the pending exeption and
 420         // continue at the next instruction after the faulting read. Returning
 421         // garbage from this read is ok.
 422         thread->set_pending_unsafe_access_error();
 423         os::Aix::ucontext_set_pc(uc, pc + 4);
 424         return 1;
 425       }
 426     }
 427 
 428     // Check to see if we caught the safepoint code in the
 429     // process of write protecting the memory serialization page.
 430     // It write enables the page immediately after protecting it
 431     // so we can just return to retry the write.
 432     if ((sig == SIGSEGV) &&
 433         os::is_memory_serialize_page(thread, addr)) {
 434       // Synchronization problem in the pseudo memory barrier code (bug id 6546278)
 435       // Block current thread until the memory serialize page permission restored.
 436       os::block_on_serialize_page_trap();
 437       return true;
 438     }
 439   }
 440 
 441 run_stub:
 442 
 443   // One of the above code blocks ininitalized the stub, so we want to
 444   // delegate control to that stub.
 445   if (stub != NULL) {
 446     // Save all thread context in case we need to restore it.
 447     if (thread != NULL) thread->set_saved_exception_pc(pc);
 448     os::Aix::ucontext_set_pc(uc, stub);
 449     return 1;
 450   }
 451 
 452 run_chained_handler:
 453 
 454   // signal-chaining
 455   if (os::Aix::chained_handler(sig, info, ucVoid)) {
 456     return 1;
 457   }
 458   if (!abort_if_unrecognized) {
 459     // caller wants another chance, so give it to him
 460     return 0;
 461   }
 462 
 463 report_and_die:
 464 
 465   // Use sigthreadmask instead of sigprocmask on AIX and unmask current signal.
 466   sigset_t newset;
 467   sigemptyset(&newset);
 468   sigaddset(&newset, sig);


< prev index next >