< prev index next >

src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp

Print this page




 701   // this si_code is so generic that it is almost meaningless; and
 702   // the si_code for this condition may change in the future.
 703   // Furthermore, a false-positive should be harmless.
 704   if (UnguardOnExecutionViolation > 0 &&
 705       (sig == SIGSEGV || sig == SIGBUS) &&
 706       uc->context_trapno == trap_page_fault) {
 707     int page_size = os::vm_page_size();
 708     address addr = (address) info->si_addr;
 709     address pc = os::Bsd::ucontext_get_pc(uc);
 710     // Make sure the pc and the faulting address are sane.
 711     //
 712     // If an instruction spans a page boundary, and the page containing
 713     // the beginning of the instruction is executable but the following
 714     // page is not, the pc and the faulting address might be slightly
 715     // different - we still want to unguard the 2nd page in this case.
 716     //
 717     // 15 bytes seems to be a (very) safe value for max instruction size.
 718     bool pc_is_near_addr =
 719       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 720     bool instr_spans_page_boundary =
 721       (align_size_down((intptr_t) pc ^ (intptr_t) addr,
 722                        (intptr_t) page_size) > 0);
 723 
 724     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 725       static volatile address last_addr =
 726         (address) os::non_memory_address_word();
 727 
 728       // In conservative mode, don't unguard unless the address is in the VM
 729       if (addr != last_addr &&
 730           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 731 
 732         // Set memory to RWX and retry
 733         address page_start = align_ptr_down(addr, page_size);
 734         bool res = os::protect_memory((char*) page_start, page_size,
 735                                       os::MEM_PROT_RWX);
 736 
 737         log_debug(os)("Execution protection violation "
 738                       "at " INTPTR_FORMAT
 739                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 740                       p2i(page_start), (res ? "success" : "failed"), errno);
 741         stub = pc;
 742 
 743         // Set last_addr so if we fault again at the same address, we don't end
 744         // up in an endless loop.
 745         //
 746         // There are two potential complications here.  Two threads trapping at
 747         // the same address at the same time could cause one of the threads to
 748         // think it already unguarded, and abort the VM.  Likely very rare.
 749         //
 750         // The other race involves two threads alternately trapping at
 751         // different addresses and failing to unguard the page, resulting in
 752         // an endless loop.  This condition is probably even more unlikely than
 753         // the first.




 701   // this si_code is so generic that it is almost meaningless; and
 702   // the si_code for this condition may change in the future.
 703   // Furthermore, a false-positive should be harmless.
 704   if (UnguardOnExecutionViolation > 0 &&
 705       (sig == SIGSEGV || sig == SIGBUS) &&
 706       uc->context_trapno == trap_page_fault) {
 707     int page_size = os::vm_page_size();
 708     address addr = (address) info->si_addr;
 709     address pc = os::Bsd::ucontext_get_pc(uc);
 710     // Make sure the pc and the faulting address are sane.
 711     //
 712     // If an instruction spans a page boundary, and the page containing
 713     // the beginning of the instruction is executable but the following
 714     // page is not, the pc and the faulting address might be slightly
 715     // different - we still want to unguard the 2nd page in this case.
 716     //
 717     // 15 bytes seems to be a (very) safe value for max instruction size.
 718     bool pc_is_near_addr =
 719       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 720     bool instr_spans_page_boundary =
 721       (align_down((intptr_t) pc ^ (intptr_t) addr,
 722                        (intptr_t) page_size) > 0);
 723 
 724     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 725       static volatile address last_addr =
 726         (address) os::non_memory_address_word();
 727 
 728       // In conservative mode, don't unguard unless the address is in the VM
 729       if (addr != last_addr &&
 730           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 731 
 732         // Set memory to RWX and retry
 733         address page_start = align_down(addr, page_size);
 734         bool res = os::protect_memory((char*) page_start, page_size,
 735                                       os::MEM_PROT_RWX);
 736 
 737         log_debug(os)("Execution protection violation "
 738                       "at " INTPTR_FORMAT
 739                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 740                       p2i(page_start), (res ? "success" : "failed"), errno);
 741         stub = pc;
 742 
 743         // Set last_addr so if we fault again at the same address, we don't end
 744         // up in an endless loop.
 745         //
 746         // There are two potential complications here.  Two threads trapping at
 747         // the same address at the same time could cause one of the threads to
 748         // think it already unguarded, and abort the VM.  Likely very rare.
 749         //
 750         // The other race involves two threads alternately trapping at
 751         // different addresses and failing to unguard the page, resulting in
 752         // an endless loop.  This condition is probably even more unlikely than
 753         // the first.


< prev index next >