115 |
115 |
116 void os::initialize_thread(Thread* thr) { |
116 void os::initialize_thread(Thread* thr) { |
117 // Nothing to do. |
117 // Nothing to do. |
118 } |
118 } |
119 |
119 |
120 address os::Linux::ucontext_get_pc(ucontext_t * uc) { |
120 address os::Linux::ucontext_get_pc(const ucontext_t * uc) { |
121 return (address)uc->uc_mcontext.gregs[REG_PC]; |
121 return (address)uc->uc_mcontext.gregs[REG_PC]; |
122 } |
122 } |
123 |
123 |
124 void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) { |
124 void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) { |
125 uc->uc_mcontext.gregs[REG_PC] = (intptr_t)pc; |
125 uc->uc_mcontext.gregs[REG_PC] = (intptr_t)pc; |
126 } |
126 } |
127 |
127 |
128 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) { |
128 intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) { |
129 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; |
129 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; |
130 } |
130 } |
131 |
131 |
132 intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) { |
132 intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { |
133 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; |
133 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; |
134 } |
134 } |
135 |
135 |
136 // For Forte Analyzer AsyncGetCallTrace profiling support - thread |
136 // For Forte Analyzer AsyncGetCallTrace profiling support - thread |
137 // is currently interrupted by SIGPROF. |
137 // is currently interrupted by SIGPROF. |
138 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal |
138 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal |
139 // frames. Currently we don't do that on Linux, so it's the same as |
139 // frames. Currently we don't do that on Linux, so it's the same as |
140 // os::fetch_frame_from_context(). |
140 // os::fetch_frame_from_context(). |
141 // This method is also used for stack overflow signal handling. |
141 // This method is also used for stack overflow signal handling. |
142 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread, |
142 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread, |
143 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
143 const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
144 |
144 |
145 assert(thread != NULL, "just checking"); |
145 assert(thread != NULL, "just checking"); |
146 assert(ret_sp != NULL, "just checking"); |
146 assert(ret_sp != NULL, "just checking"); |
147 assert(ret_fp != NULL, "just checking"); |
147 assert(ret_fp != NULL, "just checking"); |
148 |
148 |
149 return os::fetch_frame_from_context(uc, ret_sp, ret_fp); |
149 return os::fetch_frame_from_context(uc, ret_sp, ret_fp); |
150 } |
150 } |
151 |
151 |
152 ExtendedPC os::fetch_frame_from_context(void* ucVoid, |
152 ExtendedPC os::fetch_frame_from_context(const void* ucVoid, |
153 intptr_t** ret_sp, intptr_t** ret_fp) { |
153 intptr_t** ret_sp, intptr_t** ret_fp) { |
154 |
154 |
155 ExtendedPC epc; |
155 ExtendedPC epc; |
156 ucontext_t* uc = (ucontext_t*)ucVoid; |
156 const ucontext_t* uc = (const ucontext_t*)ucVoid; |
157 |
157 |
158 if (uc != NULL) { |
158 if (uc != NULL) { |
159 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); |
159 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); |
160 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); |
160 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); |
161 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); |
161 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); |
782 } |
782 } |
783 |
783 |
784 ///////////////////////////////////////////////////////////////////////////// |
784 ///////////////////////////////////////////////////////////////////////////// |
785 // helper functions for fatal error handler |
785 // helper functions for fatal error handler |
786 |
786 |
787 void os::print_context(outputStream *st, void *context) { |
787 void os::print_context(outputStream *st, const void *context) { |
788 if (context == NULL) return; |
788 if (context == NULL) return; |
789 |
789 |
790 ucontext_t *uc = (ucontext_t*)context; |
790 const ucontext_t *uc = (const ucontext_t*)context; |
791 st->print_cr("Registers:"); |
791 st->print_cr("Registers:"); |
792 #ifdef AMD64 |
792 #ifdef AMD64 |
793 st->print( "RAX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RAX]); |
793 st->print( "RAX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RAX]); |
794 st->print(", RBX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RBX]); |
794 st->print(", RBX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RBX]); |
795 st->print(", RCX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RCX]); |
795 st->print(", RCX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RCX]); |
845 address pc = os::Linux::ucontext_get_pc(uc); |
845 address pc = os::Linux::ucontext_get_pc(uc); |
846 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc)); |
846 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc)); |
847 print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
847 print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
848 } |
848 } |
849 |
849 |
850 void os::print_register_info(outputStream *st, void *context) { |
850 void os::print_register_info(outputStream *st, const void *context) { |
851 if (context == NULL) return; |
851 if (context == NULL) return; |
852 |
852 |
853 ucontext_t *uc = (ucontext_t*)context; |
853 const ucontext_t *uc = (const ucontext_t*)context; |
854 |
854 |
855 st->print_cr("Register to memory mapping:"); |
855 st->print_cr("Register to memory mapping:"); |
856 st->cr(); |
856 st->cr(); |
857 |
857 |
858 // this is horrendously verbose but the layout of the registers in the |
858 // this is horrendously verbose but the layout of the registers in the |