< prev index next >

src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp

Print this page




 618   // this si_code is so generic that it is almost meaningless; and
 619   // the si_code for this condition may change in the future.
 620   // Furthermore, a false-positive should be harmless.
 621   if (UnguardOnExecutionViolation > 0 &&
 622       (sig == SIGSEGV || sig == SIGBUS) &&
 623       uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) {  // page fault
 624     int page_size = os::vm_page_size();
 625     address addr = (address) info->si_addr;
 626     address pc = (address) uc->uc_mcontext.gregs[REG_PC];
 627     // Make sure the pc and the faulting address are sane.
 628     //
 629     // If an instruction spans a page boundary, and the page containing
 630     // the beginning of the instruction is executable but the following
 631     // page is not, the pc and the faulting address might be slightly
 632     // different - we still want to unguard the 2nd page in this case.
 633     //
 634     // 15 bytes seems to be a (very) safe value for max instruction size.
 635     bool pc_is_near_addr =
 636       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 637     bool instr_spans_page_boundary =
 638       (align_size_down((intptr_t) pc ^ (intptr_t) addr,
 639                        (intptr_t) page_size) > 0);
 640 
 641     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 642       static volatile address last_addr =
 643         (address) os::non_memory_address_word();
 644 
 645       // In conservative mode, don't unguard unless the address is in the VM
 646       if (addr != last_addr &&
 647           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 648 
 649         // Make memory rwx and retry
 650         address page_start = align_ptr_down(addr, page_size);
 651         bool res = os::protect_memory((char*) page_start, page_size,
 652                                       os::MEM_PROT_RWX);
 653 
 654         log_debug(os)("Execution protection violation "
 655                       "at " INTPTR_FORMAT
 656                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 657                       p2i(page_start), (res ? "success" : "failed"), errno);
 658         stub = pc;
 659 
 660         // Set last_addr so if we fault again at the same address, we don't end
 661         // up in an endless loop.
 662         //
 663         // There are two potential complications here.  Two threads trapping at
 664         // the same address at the same time could cause one of the threads to
 665         // think it already unguarded, and abort the VM.  Likely very rare.
 666         //
 667         // The other race involves two threads alternately trapping at
 668         // different addresses and failing to unguard the page, resulting in
 669         // an endless loop.  This condition is probably even more unlikely than
 670         // the first.




 618   // this si_code is so generic that it is almost meaningless; and
 619   // the si_code for this condition may change in the future.
 620   // Furthermore, a false-positive should be harmless.
 621   if (UnguardOnExecutionViolation > 0 &&
 622       (sig == SIGSEGV || sig == SIGBUS) &&
 623       uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) {  // page fault
 624     int page_size = os::vm_page_size();
 625     address addr = (address) info->si_addr;
 626     address pc = (address) uc->uc_mcontext.gregs[REG_PC];
 627     // Make sure the pc and the faulting address are sane.
 628     //
 629     // If an instruction spans a page boundary, and the page containing
 630     // the beginning of the instruction is executable but the following
 631     // page is not, the pc and the faulting address might be slightly
 632     // different - we still want to unguard the 2nd page in this case.
 633     //
 634     // 15 bytes seems to be a (very) safe value for max instruction size.
 635     bool pc_is_near_addr =
 636       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 637     bool instr_spans_page_boundary =
 638       (align_down((intptr_t) pc ^ (intptr_t) addr,
 639                        (intptr_t) page_size) > 0);
 640 
 641     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 642       static volatile address last_addr =
 643         (address) os::non_memory_address_word();
 644 
 645       // In conservative mode, don't unguard unless the address is in the VM
 646       if (addr != last_addr &&
 647           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 648 
 649         // Make memory rwx and retry
 650         address page_start = align_down(addr, page_size);
 651         bool res = os::protect_memory((char*) page_start, page_size,
 652                                       os::MEM_PROT_RWX);
 653 
 654         log_debug(os)("Execution protection violation "
 655                       "at " INTPTR_FORMAT
 656                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 657                       p2i(page_start), (res ? "success" : "failed"), errno);
 658         stub = pc;
 659 
 660         // Set last_addr so if we fault again at the same address, we don't end
 661         // up in an endless loop.
 662         //
 663         // There are two potential complications here.  Two threads trapping at
 664         // the same address at the same time could cause one of the threads to
 665         // think it already unguarded, and abort the VM.  Likely very rare.
 666         //
 667         // The other race involves two threads alternately trapping at
 668         // different addresses and failing to unguard the page, resulting in
 669         // an endless loop.  This condition is probably even more unlikely than
 670         // the first.


< prev index next >