< prev index next >

src/os_cpu/linux_x86/vm/os_linux_x86.cpp

Print this page




 517   // this si_code is so generic that it is almost meaningless; and
 518   // the si_code for this condition may change in the future.
 519   // Furthermore, a false-positive should be harmless.
 520   if (UnguardOnExecutionViolation > 0 &&
 521       (sig == SIGSEGV || sig == SIGBUS) &&
 522       uc->uc_mcontext.gregs[REG_TRAPNO] == trap_page_fault) {
 523     int page_size = os::vm_page_size();
 524     address addr = (address) info->si_addr;
 525     address pc = os::Linux::ucontext_get_pc(uc);
 526     // Make sure the pc and the faulting address are sane.
 527     //
 528     // If an instruction spans a page boundary, and the page containing
 529     // the beginning of the instruction is executable but the following
 530     // page is not, the pc and the faulting address might be slightly
 531     // different - we still want to unguard the 2nd page in this case.
 532     //
 533     // 15 bytes seems to be a (very) safe value for max instruction size.
 534     bool pc_is_near_addr =
 535       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 536     bool instr_spans_page_boundary =
 537       (align_size_down((intptr_t) pc ^ (intptr_t) addr,
 538                        (intptr_t) page_size) > 0);
 539 
 540     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 541       static volatile address last_addr =
 542         (address) os::non_memory_address_word();
 543 
 544       // In conservative mode, don't unguard unless the address is in the VM
 545       if (addr != last_addr &&
 546           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 547 
 548         // Set memory to RWX and retry
 549         address page_start = align_ptr_down(addr, page_size);
 550         bool res = os::protect_memory((char*) page_start, page_size,
 551                                       os::MEM_PROT_RWX);
 552 
 553         log_debug(os)("Execution protection violation "
 554                       "at " INTPTR_FORMAT
 555                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 556                       p2i(page_start), (res ? "success" : "failed"), errno);
 557         stub = pc;
 558 
 559         // Set last_addr so if we fault again at the same address, we don't end
 560         // up in an endless loop.
 561         //
 562         // There are two potential complications here.  Two threads trapping at
 563         // the same address at the same time could cause one of the threads to
 564         // think it already unguarded, and abort the VM.  Likely very rare.
 565         //
 566         // The other race involves two threads alternately trapping at
 567         // different addresses and failing to unguard the page, resulting in
 568         // an endless loop.  This condition is probably even more unlikely than
 569         // the first.




 517   // this si_code is so generic that it is almost meaningless; and
 518   // the si_code for this condition may change in the future.
 519   // Furthermore, a false-positive should be harmless.
 520   if (UnguardOnExecutionViolation > 0 &&
 521       (sig == SIGSEGV || sig == SIGBUS) &&
 522       uc->uc_mcontext.gregs[REG_TRAPNO] == trap_page_fault) {
 523     int page_size = os::vm_page_size();
 524     address addr = (address) info->si_addr;
 525     address pc = os::Linux::ucontext_get_pc(uc);
 526     // Make sure the pc and the faulting address are sane.
 527     //
 528     // If an instruction spans a page boundary, and the page containing
 529     // the beginning of the instruction is executable but the following
 530     // page is not, the pc and the faulting address might be slightly
 531     // different - we still want to unguard the 2nd page in this case.
 532     //
 533     // 15 bytes seems to be a (very) safe value for max instruction size.
 534     bool pc_is_near_addr =
 535       (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
 536     bool instr_spans_page_boundary =
 537       (align_down((intptr_t) pc ^ (intptr_t) addr,
 538                        (intptr_t) page_size) > 0);
 539 
 540     if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
 541       static volatile address last_addr =
 542         (address) os::non_memory_address_word();
 543 
 544       // In conservative mode, don't unguard unless the address is in the VM
 545       if (addr != last_addr &&
 546           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 547 
 548         // Set memory to RWX and retry
 549         address page_start = align_down(addr, page_size);
 550         bool res = os::protect_memory((char*) page_start, page_size,
 551                                       os::MEM_PROT_RWX);
 552 
 553         log_debug(os)("Execution protection violation "
 554                       "at " INTPTR_FORMAT
 555                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
 556                       p2i(page_start), (res ? "success" : "failed"), errno);
 557         stub = pc;
 558 
 559         // Set last_addr so if we fault again at the same address, we don't end
 560         // up in an endless loop.
 561         //
 562         // There are two potential complications here.  Two threads trapping at
 563         // the same address at the same time could cause one of the threads to
 564         // think it already unguarded, and abort the VM.  Likely very rare.
 565         //
 566         // The other race involves two threads alternately trapping at
 567         // different addresses and failing to unguard the page, resulting in
 568         // an endless loop.  This condition is probably even more unlikely than
 569         // the first.


< prev index next >