< 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 >