hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
changeset 35077 8b86440d3bf1
parent 35071 a0910b1d3e0d
child 35201 996db89f378e
equal deleted inserted replaced
35076:14858721b3b3 35077:8b86440d3bf1
   119 //
   119 //
   120 // Validate a ucontext retrieved from walking a uc_link of a ucontext.
   120 // Validate a ucontext retrieved from walking a uc_link of a ucontext.
   121 // There are issues with libthread giving out uc_links for different threads
   121 // There are issues with libthread giving out uc_links for different threads
   122 // on the same uc_link chain and bad or circular links.
   122 // on the same uc_link chain and bad or circular links.
   123 //
   123 //
   124 bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
   124 bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect) {
   125   if (valid >= suspect ||
   125   if (valid >= suspect ||
   126       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
   126       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
   127       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
   127       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
   128       valid->uc_stack.ss_size  != suspect->uc_stack.ss_size) {
   128       valid->uc_stack.ss_size  != suspect->uc_stack.ss_size) {
   129     DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
   129     DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
   144 }
   144 }
   145 
   145 
   146 // We will only follow one level of uc_link since there are libthread
   146 // We will only follow one level of uc_link since there are libthread
   147 // issues with ucontext linking and it is better to be safe and just
   147 // issues with ucontext linking and it is better to be safe and just
   148 // let caller retry later.
   148 // let caller retry later.
   149 ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
   149 const ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
   150   ucontext_t *uc) {
   150   const ucontext_t *uc) {
   151 
   151 
   152   ucontext_t *retuc = NULL;
   152   const ucontext_t *retuc = NULL;
   153 
   153 
   154   if (uc != NULL) {
   154   if (uc != NULL) {
   155     if (uc->uc_link == NULL) {
   155     if (uc->uc_link == NULL) {
   156       // cannot validate without uc_link so accept current ucontext
   156       // cannot validate without uc_link so accept current ucontext
   157       retuc = uc;
   157       retuc = uc;
   169   }
   169   }
   170   return retuc;
   170   return retuc;
   171 }
   171 }
   172 
   172 
   173 // Assumes ucontext is valid
   173 // Assumes ucontext is valid
   174 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
   174 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(const ucontext_t *uc) {
   175   return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]);
   175   return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]);
   176 }
   176 }
   177 
   177 
   178 void os::Solaris::ucontext_set_pc(ucontext_t* uc, address pc) {
   178 void os::Solaris::ucontext_set_pc(ucontext_t* uc, address pc) {
   179   uc->uc_mcontext.gregs [REG_PC]  = (greg_t) pc;
   179   uc->uc_mcontext.gregs [REG_PC]  = (greg_t) pc;
   180 }
   180 }
   181 
   181 
   182 // Assumes ucontext is valid
   182 // Assumes ucontext is valid
   183 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
   183 intptr_t* os::Solaris::ucontext_get_sp(const ucontext_t *uc) {
   184   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
   184   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
   185 }
   185 }
   186 
   186 
   187 // Assumes ucontext is valid
   187 // Assumes ucontext is valid
   188 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
   188 intptr_t* os::Solaris::ucontext_get_fp(const ucontext_t *uc) {
   189   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
   189   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
   190 }
   190 }
   191 
   191 
   192 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
   192 address os::Solaris::ucontext_get_pc(const ucontext_t *uc) {
   193   return (address) uc->uc_mcontext.gregs[REG_PC];
   193   return (address) uc->uc_mcontext.gregs[REG_PC];
   194 }
   194 }
   195 
   195 
   196 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
   196 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
   197 // is currently interrupted by SIGPROF.
   197 // is currently interrupted by SIGPROF.
   198 //
   198 //
   199 // The difference between this and os::fetch_frame_from_context() is that
   199 // The difference between this and os::fetch_frame_from_context() is that
   200 // here we try to skip nested signal frames.
   200 // here we try to skip nested signal frames.
   201 // This method is also used for stack overflow signal handling.
   201 // This method is also used for stack overflow signal handling.
   202 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
   202 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
   203   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
   203   const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
   204 
   204 
   205   assert(thread != NULL, "just checking");
   205   assert(thread != NULL, "just checking");
   206   assert(ret_sp != NULL, "just checking");
   206   assert(ret_sp != NULL, "just checking");
   207   assert(ret_fp != NULL, "just checking");
   207   assert(ret_fp != NULL, "just checking");
   208 
   208 
   209   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
   209   const ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
   210   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
   210   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
   211 }
   211 }
   212 
   212 
   213 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
   213 ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
   214                     intptr_t** ret_sp, intptr_t** ret_fp) {
   214                     intptr_t** ret_sp, intptr_t** ret_fp) {
   215 
   215 
   216   ExtendedPC  epc;
   216   ExtendedPC  epc;
   217   ucontext_t *uc = (ucontext_t*)ucVoid;
   217   const ucontext_t *uc = (const ucontext_t*)ucVoid;
   218 
   218 
   219   if (uc != NULL) {
   219   if (uc != NULL) {
   220     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   220     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   221     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
   221     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
   222     if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
   222     if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
   228   }
   228   }
   229 
   229 
   230   return epc;
   230   return epc;
   231 }
   231 }
   232 
   232 
   233 frame os::fetch_frame_from_context(void* ucVoid) {
   233 frame os::fetch_frame_from_context(const void* ucVoid) {
   234   intptr_t* sp;
   234   intptr_t* sp;
   235   intptr_t* fp;
   235   intptr_t* fp;
   236   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   236   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   237   return frame(sp, fp, epc.pc());
   237   return frame(sp, fp, epc.pc());
   238 }
   238 }
   772 
   772 
   773   ShouldNotReachHere();
   773   ShouldNotReachHere();
   774   return false;
   774   return false;
   775 }
   775 }
   776 
   776 
   777 void os::print_context(outputStream *st, void *context) {
   777 void os::print_context(outputStream *st, const void *context) {
   778   if (context == NULL) return;
   778   if (context == NULL) return;
   779 
   779 
   780   ucontext_t *uc = (ucontext_t*)context;
   780   const ucontext_t *uc = (const ucontext_t*)context;
   781   st->print_cr("Registers:");
   781   st->print_cr("Registers:");
   782 #ifdef AMD64
   782 #ifdef AMD64
   783   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   783   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   784   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
   784   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
   785   st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
   785   st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
   831   address pc = epc.pc();
   831   address pc = epc.pc();
   832   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
   832   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
   833   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
   833   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
   834 }
   834 }
   835 
   835 
   836 void os::print_register_info(outputStream *st, void *context) {
   836 void os::print_register_info(outputStream *st, const void *context) {
   837   if (context == NULL) return;
   837   if (context == NULL) return;
   838 
   838 
   839   ucontext_t *uc = (ucontext_t*)context;
   839   const ucontext_t *uc = (const ucontext_t*)context;
   840 
   840 
   841   st->print_cr("Register to memory mapping:");
   841   st->print_cr("Register to memory mapping:");
   842   st->cr();
   842   st->cr();
   843 
   843 
   844   // this is horrendously verbose but the layout of the registers in the
   844   // this is horrendously verbose but the layout of the registers in the