1 /* |
1 /* |
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
211 // |
211 // |
212 // ret_fp parameter is only used by Solaris X86. |
212 // ret_fp parameter is only used by Solaris X86. |
213 // |
213 // |
214 // The difference between this and os::fetch_frame_from_context() is that |
214 // The difference between this and os::fetch_frame_from_context() is that |
215 // here we try to skip nested signal frames. |
215 // here we try to skip nested signal frames. |
|
216 // This method is also used for stack overflow signal handling. |
216 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread, |
217 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread, |
217 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
218 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
218 |
219 |
219 assert(thread != NULL, "just checking"); |
220 assert(thread != NULL, "just checking"); |
220 assert(ret_sp != NULL, "just checking"); |
221 assert(ret_sp != NULL, "just checking"); |
248 frame os::fetch_frame_from_context(void* ucVoid) { |
249 frame os::fetch_frame_from_context(void* ucVoid) { |
249 intptr_t* sp; |
250 intptr_t* sp; |
250 intptr_t* fp; |
251 intptr_t* fp; |
251 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); |
252 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); |
252 return frame(sp, frame::unpatchable, epc.pc()); |
253 return frame(sp, frame::unpatchable, epc.pc()); |
|
254 } |
|
255 |
|
256 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) { |
|
257 intptr_t* sp; |
|
258 ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, NULL); |
|
259 return frame(sp, frame::unpatchable, epc.pc()); |
|
260 } |
|
261 |
|
262 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) { |
|
263 address pc = (address) os::Solaris::ucontext_get_pc(uc); |
|
264 if (Interpreter::contains(pc)) { |
|
265 *fr = os::fetch_frame_from_ucontext(thread, uc); |
|
266 if (!fr->is_first_java_frame()) { |
|
267 assert(fr->safe_for_sender(thread), "Safety check"); |
|
268 *fr = fr->java_sender(); |
|
269 } |
|
270 } else { |
|
271 // more complex code with compiled code |
|
272 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); |
|
273 CodeBlob* cb = CodeCache::find_blob(pc); |
|
274 if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { |
|
275 // Not sure where the pc points to, fallback to default |
|
276 // stack overflow handling |
|
277 return false; |
|
278 } else { |
|
279 *fr = os::fetch_frame_from_ucontext(thread, uc); |
|
280 *fr = frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); |
|
281 if (!fr->is_java_frame()) { |
|
282 assert(fr->safe_for_sender(thread), "Safety check"); |
|
283 *fr = fr->java_sender(); |
|
284 } |
|
285 } |
|
286 } |
|
287 assert(fr->is_java_frame(), "Safety check"); |
|
288 return true; |
253 } |
289 } |
254 |
290 |
255 frame os::get_sender_for_C_frame(frame* fr) { |
291 frame os::get_sender_for_C_frame(frame* fr) { |
256 return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); |
292 return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); |
257 } |
293 } |
365 |
401 |
366 // Handle ALL stack overflow variations here |
402 // Handle ALL stack overflow variations here |
367 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { |
403 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { |
368 address addr = (address) info->si_addr; |
404 address addr = (address) info->si_addr; |
369 if (thread->in_stack_yellow_zone(addr)) { |
405 if (thread->in_stack_yellow_zone(addr)) { |
370 thread->disable_stack_yellow_zone(); |
|
371 // Sometimes the register windows are not properly flushed. |
406 // Sometimes the register windows are not properly flushed. |
372 if(uc->uc_mcontext.gwins != NULL) { |
407 if(uc->uc_mcontext.gwins != NULL) { |
373 ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); |
408 ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); |
374 } |
409 } |
375 if (thread->thread_state() == _thread_in_Java) { |
410 if (thread->thread_state() == _thread_in_Java) { |
|
411 if (thread->in_stack_reserved_zone(addr)) { |
|
412 frame fr; |
|
413 if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) { |
|
414 assert(fr.is_java_frame(), "Must be a Java frame"); |
|
415 frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); |
|
416 if (activation.sp() != NULL) { |
|
417 thread->disable_stack_reserved_zone(); |
|
418 RegisterMap map(thread); |
|
419 int frame_size = activation.frame_size(&map); |
|
420 thread->set_reserved_stack_activation((address)(((address)activation.sp()) - STACK_BIAS)); |
|
421 return true; |
|
422 } |
|
423 } |
|
424 } |
376 // Throw a stack overflow exception. Guard pages will be reenabled |
425 // Throw a stack overflow exception. Guard pages will be reenabled |
377 // while unwinding the stack. |
426 // while unwinding the stack. |
|
427 thread->disable_stack_yellow_zone(); |
378 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
428 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
379 } else { |
429 } else { |
380 // Thread was in the vm or native code. Return and try to finish. |
430 // Thread was in the vm or native code. Return and try to finish. |
|
431 thread->disable_stack_yellow_zone(); |
381 return true; |
432 return true; |
382 } |
433 } |
383 } else if (thread->in_stack_red_zone(addr)) { |
434 } else if (thread->in_stack_red_zone(addr)) { |
384 // Fatal red zone violation. Disable the guard pages and fall through |
435 // Fatal red zone violation. Disable the guard pages and fall through |
385 // to handle_unexpected_exception way down below. |
436 // to handle_unexpected_exception way down below. |