< prev index next >

src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp

Print this page
rev 7970 : 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


  68 // those are to reference registers in sigcontext
  69 enum {
  70   CON_G0 = 0,
  71   CON_G1,
  72   CON_G2,
  73   CON_G3,
  74   CON_G4,
  75   CON_G5,
  76   CON_G6,
  77   CON_G7,
  78   CON_O0,
  79   CON_O1,
  80   CON_O2,
  81   CON_O3,
  82   CON_O4,
  83   CON_O5,
  84   CON_O6,
  85   CON_O7,
  86 };
  87 
  88 static inline void set_cont_address(sigcontext* ctx, address addr) {
  89   SIG_PC(ctx)  = (intptr_t)addr;
  90   SIG_NPC(ctx) = (intptr_t)(addr+4);
  91 }
  92 
  93 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
  94 // currently interrupted by SIGPROF.
  95 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested
  96 // signal frames. Currently we don't do that on Linux, so it's the
  97 // same as os::fetch_frame_from_context().
  98 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
  99                                                 ucontext_t* uc,
 100                                                 intptr_t** ret_sp,
 101                                                 intptr_t** ret_fp) {
 102   assert(thread != NULL, "just checking");
 103   assert(ret_sp != NULL, "just checking");
 104   assert(ret_fp != NULL, "just checking");
 105 
 106   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 107 }
 108 
 109 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
 110                                         intptr_t** ret_sp,
 111                                         intptr_t** ret_fp) {
 112   ucontext_t* uc = (ucontext_t*) ucVoid;


 334   st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
 335   st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
 336   st->cr();
 337 
 338   st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
 339   st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
 340   st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
 341   st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
 342   st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
 343   st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
 344   st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
 345   st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
 346   st->cr();
 347 }
 348 
 349 
 350 address os::Linux::ucontext_get_pc(ucontext_t* uc) {
 351   return (address) SIG_PC((sigcontext*)uc);
 352 }
 353 






 354 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
 355   return (intptr_t*)
 356     ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS);
 357 }
 358 
 359 // not used on Sparc
 360 intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
 361   ShouldNotReachHere();
 362   return NULL;
 363 }
 364 
 365 // Utility functions
 366 
 367 inline static bool checkPrefetch(sigcontext* uc, address pc) {
 368   if (StubRoutines::is_safefetch_fault(pc)) {
 369     set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc)));
 370     return true;
 371   }
 372   return false;
 373 }
 374 
 375 inline static bool checkOverflow(sigcontext* uc,
 376                                  address pc,
 377                                  address addr,
 378                                  JavaThread* thread,
 379                                  address* stub) {
 380   // check if fault address is within thread stack
 381   if (addr < thread->stack_base() &&
 382       addr >= thread->stack_base() - thread->stack_size()) {
 383     // stack overflow
 384     if (thread->in_stack_yellow_zone(addr)) {
 385       thread->disable_stack_yellow_zone();
 386       if (thread->thread_state() == _thread_in_Java) {
 387         // Throw a stack overflow exception.  Guard pages will be reenabled
 388         // while unwinding the stack.
 389         *stub =


 649           break;
 650         }
 651 
 652         if ((sig == SIGSEGV) &&
 653             checkNullPointer(pc, (intptr_t)info->si_addr, thread, &stub)) {
 654           break;
 655         }
 656       } while (0);
 657 
 658       // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
 659       // and the heap gets shrunk before the field access.
 660       if ((sig == SIGSEGV) || (sig == SIGBUS)) {
 661         checkFastJNIAccess(pc, &stub);
 662       }
 663     }
 664 
 665     if (stub != NULL) {
 666       // save all thread context in case we need to restore it
 667       thread->set_saved_exception_pc(pc);
 668       thread->set_saved_exception_npc(npc);
 669       set_cont_address(uc, stub);
 670       return true;
 671     }
 672   }
 673 
 674   // signal-chaining
 675   if (os::Linux::chained_handler(sig, info, ucVoid)) {
 676     return true;
 677   }
 678 
 679   if (!abort_if_unrecognized) {
 680     // caller wants another chance, so give it to him
 681     return false;
 682   }
 683 
 684   if (pc == NULL && uc != NULL) {
 685     pc = os::Linux::ucontext_get_pc((ucontext_t*)uc);
 686   }
 687 
 688   // unmask current signal
 689   sigset_t newset;




  68 // those are to reference registers in sigcontext
  69 enum {
  70   CON_G0 = 0,
  71   CON_G1,
  72   CON_G2,
  73   CON_G3,
  74   CON_G4,
  75   CON_G5,
  76   CON_G6,
  77   CON_G7,
  78   CON_O0,
  79   CON_O1,
  80   CON_O2,
  81   CON_O3,
  82   CON_O4,
  83   CON_O5,
  84   CON_O6,
  85   CON_O7,
  86 };
  87 





  88 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
  89 // currently interrupted by SIGPROF.
  90 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested
  91 // signal frames. Currently we don't do that on Linux, so it's the
  92 // same as os::fetch_frame_from_context().
  93 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
  94                                                 ucontext_t* uc,
  95                                                 intptr_t** ret_sp,
  96                                                 intptr_t** ret_fp) {
  97   assert(thread != NULL, "just checking");
  98   assert(ret_sp != NULL, "just checking");
  99   assert(ret_fp != NULL, "just checking");
 100 
 101   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 102 }
 103 
 104 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
 105                                         intptr_t** ret_sp,
 106                                         intptr_t** ret_fp) {
 107   ucontext_t* uc = (ucontext_t*) ucVoid;


 329   st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
 330   st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
 331   st->cr();
 332 
 333   st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
 334   st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
 335   st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
 336   st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
 337   st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
 338   st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
 339   st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
 340   st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
 341   st->cr();
 342 }
 343 
 344 
 345 address os::Linux::ucontext_get_pc(ucontext_t* uc) {
 346   return (address) SIG_PC((sigcontext*)uc);
 347 }
 348 
 349 void os::Linux::ucontext_set_pc(ucontext_t* uc, address pc) {
 350   sigcontext_t* ctx = (sigcontext_t*) uc;
 351   SIG_PC(ctx)  = (intptr_t)addr;
 352   SIG_NPC(ctx) = (intptr_t)(addr+4);
 353 }
 354 
 355 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
 356   return (intptr_t*)
 357     ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS);
 358 }
 359 
 360 // not used on Sparc
 361 intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
 362   ShouldNotReachHere();
 363   return NULL;
 364 }
 365 
 366 // Utility functions
 367 
 368 inline static bool checkPrefetch(sigcontext* uc, address pc) {
 369   if (StubRoutines::is_safefetch_fault(pc)) {
 370     os::Linux::ucontext_set_pc((ucontext_t*)uc, StubRoutines::continuation_for_safefetch_fault(pc));
 371     return true;
 372   }
 373   return false;
 374 }
 375 
 376 inline static bool checkOverflow(sigcontext* uc,
 377                                  address pc,
 378                                  address addr,
 379                                  JavaThread* thread,
 380                                  address* stub) {
 381   // check if fault address is within thread stack
 382   if (addr < thread->stack_base() &&
 383       addr >= thread->stack_base() - thread->stack_size()) {
 384     // stack overflow
 385     if (thread->in_stack_yellow_zone(addr)) {
 386       thread->disable_stack_yellow_zone();
 387       if (thread->thread_state() == _thread_in_Java) {
 388         // Throw a stack overflow exception.  Guard pages will be reenabled
 389         // while unwinding the stack.
 390         *stub =


 650           break;
 651         }
 652 
 653         if ((sig == SIGSEGV) &&
 654             checkNullPointer(pc, (intptr_t)info->si_addr, thread, &stub)) {
 655           break;
 656         }
 657       } while (0);
 658 
 659       // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
 660       // and the heap gets shrunk before the field access.
 661       if ((sig == SIGSEGV) || (sig == SIGBUS)) {
 662         checkFastJNIAccess(pc, &stub);
 663       }
 664     }
 665 
 666     if (stub != NULL) {
 667       // save all thread context in case we need to restore it
 668       thread->set_saved_exception_pc(pc);
 669       thread->set_saved_exception_npc(npc);
 670       os::Linux::ucontext_set_pc((ucontext_t*)uc, stub);
 671       return true;
 672     }
 673   }
 674 
 675   // signal-chaining
 676   if (os::Linux::chained_handler(sig, info, ucVoid)) {
 677     return true;
 678   }
 679 
 680   if (!abort_if_unrecognized) {
 681     // caller wants another chance, so give it to him
 682     return false;
 683   }
 684 
 685   if (pc == NULL && uc != NULL) {
 686     pc = os::Linux::ucontext_get_pc((ucontext_t*)uc);
 687   }
 688 
 689   // unmask current signal
 690   sigset_t newset;


< prev index next >