180
181 // Assumes ucontext is valid
182 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
183 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
184 }
185
186 // Assumes ucontext is valid
187 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
188 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
189 }
190
191 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
192 return (address) uc->uc_mcontext.gregs[REG_PC];
193 }
194
195 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
196 // is currently interrupted by SIGPROF.
197 //
198 // The difference between this and os::fetch_frame_from_context() is that
199 // here we try to skip nested signal frames.
200 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
201 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
202
203 assert(thread != NULL, "just checking");
204 assert(ret_sp != NULL, "just checking");
205 assert(ret_fp != NULL, "just checking");
206
207 ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
208 return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
209 }
210
211 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
212 intptr_t** ret_sp, intptr_t** ret_fp) {
213
214 ExtendedPC epc;
215 ucontext_t *uc = (ucontext_t*)ucVoid;
216
217 if (uc != NULL) {
218 epc = os::Solaris::ucontext_get_ExtendedPC(uc);
219 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
220 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
221 } else {
222 // construct empty ExtendedPC for return value checking
223 epc = ExtendedPC(NULL);
224 if (ret_sp) *ret_sp = (intptr_t *)NULL;
225 if (ret_fp) *ret_fp = (intptr_t *)NULL;
226 }
227
228 return epc;
229 }
230
231 frame os::fetch_frame_from_context(void* ucVoid) {
232 intptr_t* sp;
233 intptr_t* fp;
234 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
235 return frame(sp, fp, epc.pc());
236 }
237
238 frame os::get_sender_for_C_frame(frame* fr) {
239 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
240 }
241
242 extern "C" intptr_t *_get_current_sp(); // in .il file
243
244 address os::current_stack_pointer() {
245 return (address)_get_current_sp();
246 }
247
248 extern "C" intptr_t *_get_current_fp(); // in .il file
249
250 frame os::current_frame() {
251 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
252 frame myframe((intptr_t*)os::current_stack_pointer(),
253 (intptr_t*)fp,
254 CAST_FROM_FN_PTR(address, os::current_frame));
255 if (os::is_first_C_frame(&myframe)) {
256 // stack is not walkable
257 frame ret; // This will be a null useless frame
406
407 // decide if this trap can be handled by a stub
408 address stub = NULL;
409
410 address pc = NULL;
411
412 //%note os_trap_1
413 if (info != NULL && uc != NULL && thread != NULL) {
414 // factor me: getPCfromContext
415 pc = (address) uc->uc_mcontext.gregs[REG_PC];
416
417 if (StubRoutines::is_safefetch_fault(pc)) {
418 os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
419 return true;
420 }
421
422 // Handle ALL stack overflow variations here
423 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
424 address addr = (address) info->si_addr;
425 if (thread->in_stack_yellow_zone(addr)) {
426 thread->disable_stack_yellow_zone();
427 if (thread->thread_state() == _thread_in_Java) {
428 // Throw a stack overflow exception. Guard pages will be reenabled
429 // while unwinding the stack.
430 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
431 } else {
432 // Thread was in the vm or native code. Return and try to finish.
433 return true;
434 }
435 } else if (thread->in_stack_red_zone(addr)) {
436 // Fatal red zone violation. Disable the guard pages and fall through
437 // to handle_unexpected_exception way down below.
438 thread->disable_stack_red_zone();
439 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
440 }
441 }
442
443 if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
444 // Verify that OS save/restore AVX registers.
445 stub = VM_Version::cpuinfo_cont_addr();
446 }
447
448 if (thread->thread_state() == _thread_in_vm) {
449 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
450 stub = StubRoutines::handler_for_unsafe_access();
451 }
452 }
|
180
181 // Assumes ucontext is valid
182 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
183 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
184 }
185
186 // Assumes ucontext is valid
187 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
188 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
189 }
190
191 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
192 return (address) uc->uc_mcontext.gregs[REG_PC];
193 }
194
195 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
196 // is currently interrupted by SIGPROF.
197 //
198 // The difference between this and os::fetch_frame_from_context() is that
199 // here we try to skip nested signal frames.
200 // This method is also used for stack overflow signal handling.
201 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
202 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
203
204 assert(thread != NULL, "just checking");
205 assert(ret_sp != NULL, "just checking");
206 assert(ret_fp != NULL, "just checking");
207
208 ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
209 return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
210 }
211
212 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
213 intptr_t** ret_sp, intptr_t** ret_fp) {
214
215 ExtendedPC epc;
216 ucontext_t *uc = (ucontext_t*)ucVoid;
217
218 if (uc != NULL) {
219 epc = os::Solaris::ucontext_get_ExtendedPC(uc);
220 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
221 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
222 } else {
223 // construct empty ExtendedPC for return value checking
224 epc = ExtendedPC(NULL);
225 if (ret_sp) *ret_sp = (intptr_t *)NULL;
226 if (ret_fp) *ret_fp = (intptr_t *)NULL;
227 }
228
229 return epc;
230 }
231
232 frame os::fetch_frame_from_context(void* ucVoid) {
233 intptr_t* sp;
234 intptr_t* fp;
235 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
236 return frame(sp, fp, epc.pc());
237 }
238
239 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
240 intptr_t* sp;
241 intptr_t* fp;
242 ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
243 return frame(sp, fp, epc.pc());
244 }
245
246 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
247 address pc = (address) os::Solaris::ucontext_get_pc(uc);
248 if (Interpreter::contains(pc)) {
249 // interpreter performs stack banging after the fixed frame header has
250 // been generated while the compilers perform it before. To maintain
251 // semantic consistency between interpreted and compiled frames, the
252 // method returns the Java sender of the current frame.
253 *fr = os::fetch_frame_from_ucontext(thread, uc);
254 if (!fr->is_first_java_frame()) {
255 assert(fr->safe_for_sender(thread), "Safety check");
256 *fr = fr->java_sender();
257 }
258 } else {
259 // more complex code with compiled code
260 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
261 CodeBlob* cb = CodeCache::find_blob(pc);
262 if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
263 // Not sure where the pc points to, fallback to default
264 // stack overflow handling
265 return false;
266 } else {
267 // in compiled code, the stack banging is performed just after the return pc
268 // has been pushed on the stack
269 intptr_t* fp = os::Solaris::ucontext_get_fp(uc);
270 intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
271 *fr = frame(sp + 1, fp, (address)*sp);
272 if (!fr->is_java_frame()) {
273 assert(fr->safe_for_sender(thread), "Safety check");
274 *fr = fr->java_sender();
275 }
276 }
277 }
278 assert(fr->is_java_frame(), "Safety check");
279 return true;
280 }
281
282 frame os::get_sender_for_C_frame(frame* fr) {
283 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
284 }
285
286 extern "C" intptr_t *_get_current_sp(); // in .il file
287
288 address os::current_stack_pointer() {
289 return (address)_get_current_sp();
290 }
291
292 extern "C" intptr_t *_get_current_fp(); // in .il file
293
294 frame os::current_frame() {
295 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
296 frame myframe((intptr_t*)os::current_stack_pointer(),
297 (intptr_t*)fp,
298 CAST_FROM_FN_PTR(address, os::current_frame));
299 if (os::is_first_C_frame(&myframe)) {
300 // stack is not walkable
301 frame ret; // This will be a null useless frame
450
451 // decide if this trap can be handled by a stub
452 address stub = NULL;
453
454 address pc = NULL;
455
456 //%note os_trap_1
457 if (info != NULL && uc != NULL && thread != NULL) {
458 // factor me: getPCfromContext
459 pc = (address) uc->uc_mcontext.gregs[REG_PC];
460
461 if (StubRoutines::is_safefetch_fault(pc)) {
462 os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
463 return true;
464 }
465
466 // Handle ALL stack overflow variations here
467 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
468 address addr = (address) info->si_addr;
469 if (thread->in_stack_yellow_zone(addr)) {
470 if (thread->thread_state() == _thread_in_Java) {
471 if (thread->in_stack_reserved_zone(addr)) {
472 frame fr;
473 if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
474 assert(fr.is_java_frame(), "Must be Java frame");
475 frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
476 if (activation.sp() != NULL) {
477 thread->disable_stack_reserved_zone();
478 if (activation.is_interpreted_frame()) {
479 thread->set_reserved_stack_activation((address)(
480 activation.fp() + frame::interpreter_frame_initial_sp_offset));
481 } else {
482 thread->set_reserved_stack_activation((address)activation.unextended_sp());
483 }
484 return true;
485 }
486 }
487 }
488 // Throw a stack overflow exception. Guard pages will be reenabled
489 // while unwinding the stack.
490 thread->disable_stack_yellow_zone();
491 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
492 } else {
493 // Thread was in the vm or native code. Return and try to finish.
494 thread->disable_stack_yellow_zone();
495 return true;
496 }
497 } else if (thread->in_stack_red_zone(addr)) {
498 // Fatal red zone violation. Disable the guard pages and fall through
499 // to handle_unexpected_exception way down below.
500 thread->disable_stack_red_zone();
501 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
502 }
503 }
504
505 if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
506 // Verify that OS save/restore AVX registers.
507 stub = VM_Version::cpuinfo_cont_addr();
508 }
509
510 if (thread->thread_state() == _thread_in_vm) {
511 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
512 stub = StubRoutines::handler_for_unsafe_access();
513 }
514 }
|