< prev index next >

src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp

Print this page
rev 54204 : 8220794: PPC64: Fix signal handler for SIGSEGV on branch to illegal address
Reviewed-by:

*** 130,139 **** --- 130,143 ---- intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { return NULL; } + static unsigned long ucontext_get_trap(const ucontext_t * uc) { + return uc->uc_mcontext.regs->trap; + } + ExtendedPC os::fetch_frame_from_context(const void* ucVoid, intptr_t** ret_sp, intptr_t** ret_fp) { ExtendedPC epc; const ucontext_t* uc = (const ucontext_t*)ucVoid;
*** 302,314 **** if (info != NULL && uc != NULL && thread != NULL) { pc = (address) os::Linux::ucontext_get_pc(uc); // Handle ALL stack overflow variations here if (sig == SIGSEGV) { ! // Si_addr may not be valid due to a bug in the linux-ppc64 kernel (see // comment below). Use get_stack_bang_address instead of si_addr. ! address addr = ((NativeInstruction*)pc)->get_stack_bang_address(uc); // Check if fault address is within thread stack. if (thread->on_local_stack(addr)) { // stack overflow if (thread->in_stack_yellow_reserved_zone(addr)) { --- 306,331 ---- if (info != NULL && uc != NULL && thread != NULL) { pc = (address) os::Linux::ucontext_get_pc(uc); // Handle ALL stack overflow variations here if (sig == SIGSEGV) { ! // si_addr may not be valid due to a bug in the linux-ppc64 kernel (see // comment below). Use get_stack_bang_address instead of si_addr. ! // If SIGSEGV is caused due to a branch to an invalid address an ! // "Instruction Storage" interruption is generated and 'pc' (NIP) already ! // contains the invalid address. Otherwise, the SIGSEGV is caused due to ! // load/store instruction trying to load/store from/to an invalid address ! // and causing a "Data Storage" interruption, so we inspect the intruction ! // in order to extract the faulty data addresss. ! address addr; ! if ((ucontext_get_trap(uc) & 0x0F00 /* no IRQ reply bits */) == 0x0400) { ! // Instruction interruption ! addr = pc; ! } else { ! // Data interruption (0x0300): extract faulty data address ! addr = ((NativeInstruction*)pc)->get_stack_bang_address(uc); ! } // Check if fault address is within thread stack. if (thread->on_local_stack(addr)) { // stack overflow if (thread->in_stack_yellow_reserved_zone(addr)) {
< prev index next >