< prev index next >

src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp

Print this page
rev 7968 : 8074552:  SafeFetch32 and SafeFetchN do not work in error handling
Summary: handle SafeFetch faults in secondary signal handlers
Reviewed-by: dholmes
Contributed-by: Thomas Stuefe


 167       uc = uc->uc_link;
 168       if (uc->uc_link == NULL) {
 169         // cannot validate without uc_link so accept current ucontext
 170         retuc = uc;
 171       } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
 172         // the ucontext one level down is also valid so return it
 173         retuc = uc;
 174       }
 175     }
 176   }
 177   return retuc;
 178 }
 179 
 180 // Assumes ucontext is valid
 181 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
 182   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
 183   // set npc to zero to avoid using it for safepoint, good for profiling only
 184   return ExtendedPC(pc);
 185 }
 186 





 187 // Assumes ucontext is valid
 188 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 189   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
 190 }
 191 
 192 // Solaris X86 only
 193 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 194   ShouldNotReachHere();
 195   return NULL;
 196 }
 197 
 198 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
 199   return (address) uc->uc_mcontext.gregs[REG_PC];
 200 }
 201 
 202 
 203 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 204 // is currently interrupted by SIGPROF.
 205 //
 206 // ret_fp parameter is only used by Solaris X86.


 338     // can't decode this kind of signal
 339     info = NULL;
 340   } else {
 341     assert(sig == info->si_signo, "bad siginfo");
 342   }
 343 
 344   // decide if this trap can be handled by a stub
 345   address stub = NULL;
 346 
 347   address pc          = NULL;
 348   address npc         = NULL;
 349 
 350   //%note os_trap_1
 351   if (info != NULL && uc != NULL && thread != NULL) {
 352     // factor me: getPCfromContext
 353     pc  = (address) uc->uc_mcontext.gregs[REG_PC];
 354     npc = (address) uc->uc_mcontext.gregs[REG_nPC];
 355 
 356     // SafeFetch() support
 357     if (StubRoutines::is_safefetch_fault(pc)) {
 358       uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
 359       uc->uc_mcontext.gregs[REG_nPC] = uc->uc_mcontext.gregs[REG_PC] + 4;
 360       return 1;
 361     }
 362 
 363     // Handle ALL stack overflow variations here
 364     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 365       address addr = (address) info->si_addr;
 366       if (thread->in_stack_yellow_zone(addr)) {
 367         thread->disable_stack_yellow_zone();
 368         // Sometimes the register windows are not properly flushed.
 369         if(uc->uc_mcontext.gwins != NULL) {
 370           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 371         }
 372         if (thread->thread_state() == _thread_in_Java) {
 373           // Throw a stack overflow exception.  Guard pages will be reenabled
 374           // while unwinding the stack.
 375           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 376         } else {
 377           // Thread was in the vm or native code.  Return and try to finish.
 378           return true;
 379         }


 477     // Check to see if we caught the safepoint code in the
 478     // process of write protecting the memory serialization page.
 479     // It write enables the page immediately after protecting it
 480     // so just return.
 481     if ((sig == SIGSEGV) &&
 482         os::is_memory_serialize_page(thread, (address)info->si_addr)) {
 483       // Block current thread until the memory serialize page permission restored.
 484       os::block_on_serialize_page_trap();
 485       return true;
 486     }
 487   }
 488 
 489   if (stub != NULL) {
 490     // save all thread context in case we need to restore it
 491 
 492     thread->set_saved_exception_pc(pc);
 493     thread->set_saved_exception_npc(npc);
 494 
 495     // simulate a branch to the stub (a "call" in the safepoint stub case)
 496     // factor me: setPC
 497     uc->uc_mcontext.gregs[REG_PC ] = (greg_t)stub;
 498     uc->uc_mcontext.gregs[REG_nPC] = (greg_t)(stub + 4);
 499 
 500 #ifndef PRODUCT
 501     if (TraceJumps) thread->record_jump(stub, NULL, __FILE__, __LINE__);
 502 #endif /* PRODUCT */
 503 
 504     return true;
 505   }
 506 
 507   // signal-chaining
 508   if (os::Solaris::chained_handler(sig, info, ucVoid)) {
 509     return true;
 510   }
 511 
 512   if (!abort_if_unrecognized) {
 513     // caller wants another chance, so give it to him
 514     return false;
 515   }
 516 
 517   if (!os::Solaris::libjsig_is_loaded) {
 518     struct sigaction oldAct;




 167       uc = uc->uc_link;
 168       if (uc->uc_link == NULL) {
 169         // cannot validate without uc_link so accept current ucontext
 170         retuc = uc;
 171       } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
 172         // the ucontext one level down is also valid so return it
 173         retuc = uc;
 174       }
 175     }
 176   }
 177   return retuc;
 178 }
 179 
 180 // Assumes ucontext is valid
 181 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
 182   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
 183   // set npc to zero to avoid using it for safepoint, good for profiling only
 184   return ExtendedPC(pc);
 185 }
 186 
 187 void os::Solaris::ucontext_set_pc(ucontext_t* uc, address pc) {
 188   uc->uc_mcontext.gregs [REG_PC]  = (greg_t) pc;
 189   uc->uc_mcontext.gregs [REG_nPC] = (greg_t) (pc + 4);
 190 }
 191 
 192 // Assumes ucontext is valid
 193 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 194   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
 195 }
 196 
 197 // Solaris X86 only
 198 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 199   ShouldNotReachHere();
 200   return NULL;
 201 }
 202 
 203 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
 204   return (address) uc->uc_mcontext.gregs[REG_PC];
 205 }
 206 
 207 
 208 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 209 // is currently interrupted by SIGPROF.
 210 //
 211 // ret_fp parameter is only used by Solaris X86.


 343     // can't decode this kind of signal
 344     info = NULL;
 345   } else {
 346     assert(sig == info->si_signo, "bad siginfo");
 347   }
 348 
 349   // decide if this trap can be handled by a stub
 350   address stub = NULL;
 351 
 352   address pc          = NULL;
 353   address npc         = NULL;
 354 
 355   //%note os_trap_1
 356   if (info != NULL && uc != NULL && thread != NULL) {
 357     // factor me: getPCfromContext
 358     pc  = (address) uc->uc_mcontext.gregs[REG_PC];
 359     npc = (address) uc->uc_mcontext.gregs[REG_nPC];
 360 
 361     // SafeFetch() support
 362     if (StubRoutines::is_safefetch_fault(pc)) {
 363       os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));

 364       return 1;
 365     }
 366 
 367     // Handle ALL stack overflow variations here
 368     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 369       address addr = (address) info->si_addr;
 370       if (thread->in_stack_yellow_zone(addr)) {
 371         thread->disable_stack_yellow_zone();
 372         // Sometimes the register windows are not properly flushed.
 373         if(uc->uc_mcontext.gwins != NULL) {
 374           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 375         }
 376         if (thread->thread_state() == _thread_in_Java) {
 377           // Throw a stack overflow exception.  Guard pages will be reenabled
 378           // while unwinding the stack.
 379           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 380         } else {
 381           // Thread was in the vm or native code.  Return and try to finish.
 382           return true;
 383         }


 481     // Check to see if we caught the safepoint code in the
 482     // process of write protecting the memory serialization page.
 483     // It write enables the page immediately after protecting it
 484     // so just return.
 485     if ((sig == SIGSEGV) &&
 486         os::is_memory_serialize_page(thread, (address)info->si_addr)) {
 487       // Block current thread until the memory serialize page permission restored.
 488       os::block_on_serialize_page_trap();
 489       return true;
 490     }
 491   }
 492 
 493   if (stub != NULL) {
 494     // save all thread context in case we need to restore it
 495 
 496     thread->set_saved_exception_pc(pc);
 497     thread->set_saved_exception_npc(npc);
 498 
 499     // simulate a branch to the stub (a "call" in the safepoint stub case)
 500     // factor me: setPC
 501     os::Solaris::ucontext_set_pc(uc, stub);

 502 
 503 #ifndef PRODUCT
 504     if (TraceJumps) thread->record_jump(stub, NULL, __FILE__, __LINE__);
 505 #endif /* PRODUCT */
 506 
 507     return true;
 508   }
 509 
 510   // signal-chaining
 511   if (os::Solaris::chained_handler(sig, info, ucVoid)) {
 512     return true;
 513   }
 514 
 515   if (!abort_if_unrecognized) {
 516     // caller wants another chance, so give it to him
 517     return false;
 518   }
 519 
 520   if (!os::Solaris::libjsig_is_loaded) {
 521     struct sigaction oldAct;


< prev index next >