257 JavaThread* thread = NULL; |
257 JavaThread* thread = NULL; |
258 VMThread* vmthread = NULL; |
258 VMThread* vmthread = NULL; |
259 if (os::Linux::signal_handlers_are_installed) { |
259 if (os::Linux::signal_handlers_are_installed) { |
260 if (t != NULL ){ |
260 if (t != NULL ){ |
261 if(t->is_Java_thread()) { |
261 if(t->is_Java_thread()) { |
262 #ifndef PRODUCT |
262 #ifdef PRINT_SIGNAL_HANDLE |
263 //tty->print_cr("this thread is a java thread"); |
263 //tty->print_cr("this thread is a java thread"); |
264 #endif |
264 #endif |
265 thread = (JavaThread*)t; |
265 thread = (JavaThread*)t; |
266 } |
266 } |
267 else if(t->is_VM_thread()){ |
267 else if(t->is_VM_thread()){ |
268 #ifndef PRODUCT |
268 #ifdef PRINT_SIGNAL_HANDLE |
269 //tty->print_cr("this thread is a VM thread\n"); |
269 //tty->print_cr("this thread is a VM thread\n"); |
270 #endif |
270 #endif |
271 vmthread = (VMThread *)t; |
271 vmthread = (VMThread *)t; |
272 } |
272 } |
273 } |
273 } |
276 // decide if this trap can be handled by a stub |
276 // decide if this trap can be handled by a stub |
277 address stub = NULL; |
277 address stub = NULL; |
278 address pc = NULL; |
278 address pc = NULL; |
279 |
279 |
280 pc = (address) os::Linux::ucontext_get_pc(uc); |
280 pc = (address) os::Linux::ucontext_get_pc(uc); |
281 #ifndef PRODUCT |
281 #ifdef PRINT_SIGNAL_HANDLE |
282 tty->print_cr("pc=%lx", pc); |
282 tty->print_cr("pc=%lx", pc); |
283 os::print_context(tty, uc); |
283 os::print_context(tty, uc); |
284 #endif |
284 #endif |
285 //%note os_trap_1 |
285 //%note os_trap_1 |
286 if (info != NULL && uc != NULL && thread != NULL) { |
286 if (info != NULL && uc != NULL && thread != NULL) { |
287 pc = (address) os::Linux::ucontext_get_pc(uc); |
287 pc = (address) os::Linux::ucontext_get_pc(uc); |
288 // Handle ALL stack overflow variations here |
288 // Handle ALL stack overflow variations here |
289 if (sig == SIGSEGV) { |
289 if (sig == SIGSEGV) { |
290 address addr = (address) info->si_addr; |
290 address addr = (address) info->si_addr; |
291 // check if fault address is within thread stack |
291 // check if fault address is within thread stack |
292 #ifndef PRODUCT |
292 #ifdef PRINT_SIGNAL_HANDLE |
293 //tty->print("handle all stack overflow variations: "); |
293 //tty->print("handle all stack overflow variations: "); |
294 /*tty->print("addr = %lx, stack base = %lx, stack top = %lx\n", |
294 /*tty->print("addr = %lx, stack base = %lx, stack top = %lx\n", |
295 addr, |
295 addr, |
296 thread->stack_base(), |
296 thread->stack_base(), |
297 thread->stack_base() - thread->stack_size()); |
297 thread->stack_base() - thread->stack_size()); |
299 #endif |
299 #endif |
300 |
300 |
301 if (addr < thread->stack_base() && |
301 if (addr < thread->stack_base() && |
302 addr >= thread->stack_base() - thread->stack_size()) { |
302 addr >= thread->stack_base() - thread->stack_size()) { |
303 // stack overflow |
303 // stack overflow |
304 #ifndef PRODUCT |
304 #ifdef PRINT_SIGNAL_HANDLE |
305 tty->print("stack exception check \n"); |
305 tty->print("stack exception check \n"); |
306 #endif |
306 #endif |
307 if (thread->in_stack_yellow_zone(addr)) { |
307 if (thread->in_stack_yellow_zone(addr)) { |
308 #ifndef PRODUCT |
308 #ifdef PRINT_SIGNAL_HANDLE |
309 tty->print("exception addr is in yellow zone\n"); |
309 tty->print("exception addr is in yellow zone\n"); |
310 #endif |
310 #endif |
311 thread->disable_stack_yellow_zone(); |
311 thread->disable_stack_yellow_zone(); |
312 if (thread->thread_state() == _thread_in_Java) { |
312 if (thread->thread_state() == _thread_in_Java) { |
313 // Throw a stack overflow exception. Guard pages will be reenabled |
313 // Throw a stack overflow exception. Guard pages will be reenabled |
314 // while unwinding the stack. |
314 // while unwinding the stack. |
315 #ifndef PRODUCT |
315 #ifdef PRINT_SIGNAL_HANDLE |
316 tty->print("this thread is in java\n"); |
316 tty->print("this thread is in java\n"); |
317 #endif |
317 #endif |
318 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
318 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
319 } else { |
319 } else { |
320 // Thread was in the vm or native code. Return and try to finish. |
320 // Thread was in the vm or native code. Return and try to finish. |
321 #ifndef PRODUCT |
321 #ifdef PRINT_SIGNAL_HANDLE |
322 tty->print("this thread is in vm or native codes and return\n"); |
322 tty->print("this thread is in vm or native codes and return\n"); |
323 #endif |
323 #endif |
324 return 1; |
324 return 1; |
325 } |
325 } |
326 } else if (thread->in_stack_red_zone(addr)) { |
326 } else if (thread->in_stack_red_zone(addr)) { |
327 // Fatal red zone violation. Disable the guard pages and fall through |
327 // Fatal red zone violation. Disable the guard pages and fall through |
328 // to handle_unexpected_exception way down below. |
328 // to handle_unexpected_exception way down below. |
329 #ifndef PRODUCT |
329 #ifdef PRINT_SIGNAL_HANDLE |
330 tty->print("exception addr is in red zone\n"); |
330 tty->print("exception addr is in red zone\n"); |
331 #endif |
331 #endif |
332 thread->disable_stack_red_zone(); |
332 thread->disable_stack_red_zone(); |
333 #ifndef PRODUCT |
333 #ifdef PRINT_SIGNAL_HANDLE |
334 tty->print_raw_cr("An irrecoverable stack overflow has occurred."); |
334 tty->print_raw_cr("An irrecoverable stack overflow has occurred."); |
335 #endif |
335 #endif |
336 } else { |
336 } else { |
337 // Accessing stack address below sp may cause SEGV if current |
337 // Accessing stack address below sp may cause SEGV if current |
338 // thread has MAP_GROWSDOWN stack. This should only happen when |
338 // thread has MAP_GROWSDOWN stack. This should only happen when |
339 // current thread was created by user code with MAP_GROWSDOWN flag |
339 // current thread was created by user code with MAP_GROWSDOWN flag |
340 // and then attached to VM. See notes in os_linux.cpp. |
340 // and then attached to VM. See notes in os_linux.cpp. |
341 #ifndef PRODUCT |
341 #ifdef PRINT_SIGNAL_HANDLE |
342 tty->print("exception addr is neither in yellow zone nor in the red one\n"); |
342 tty->print("exception addr is neither in yellow zone nor in the red one\n"); |
343 #endif |
343 #endif |
344 if (thread->osthread()->expanding_stack() == 0) { |
344 if (thread->osthread()->expanding_stack() == 0) { |
345 thread->osthread()->set_expanding_stack(); |
345 thread->osthread()->set_expanding_stack(); |
346 if (os::Linux::manually_expand_stack(thread, addr)) { |
346 if (os::Linux::manually_expand_stack(thread, addr)) { |
356 } //sig == SIGSEGV |
356 } //sig == SIGSEGV |
357 |
357 |
358 if (thread->thread_state() == _thread_in_Java) { |
358 if (thread->thread_state() == _thread_in_Java) { |
359 // Java thread running in Java code => find exception handler if any |
359 // Java thread running in Java code => find exception handler if any |
360 // a fault inside compiled code, the interpreter, or a stub |
360 // a fault inside compiled code, the interpreter, or a stub |
361 #ifndef PRODUCT |
361 #ifdef PRINT_SIGNAL_HANDLE |
362 tty->print("java thread running in java code\n"); |
362 tty->print("java thread running in java code\n"); |
363 tty->print_cr("polling address = %lx, sig=%d", os::get_polling_page(), sig); |
363 tty->print_cr("polling address = %lx, sig=%d", os::get_polling_page(), sig); |
364 #endif |
364 #endif |
365 if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) { |
365 if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) { |
366 |
366 |
369 // BugId 4454115: A read from a MappedByteBuffer can fault |
369 // BugId 4454115: A read from a MappedByteBuffer can fault |
370 // here if the underlying file has been truncated. |
370 // here if the underlying file has been truncated. |
371 // Do not crash the VM in such a case. |
371 // Do not crash the VM in such a case. |
372 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
372 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
373 nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; |
373 nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; |
374 #ifndef PRODUCT |
374 #ifdef PRINT_SIGNAL_HANDLE |
375 tty->print("cb = %lx, nm = %lx\n", cb, nm); |
375 tty->print("cb = %lx, nm = %lx\n", cb, nm); |
376 #endif |
376 #endif |
377 if (nm != NULL && nm->has_unsafe_access()) { |
377 if (nm != NULL && nm->has_unsafe_access()) { |
378 stub = StubRoutines::handler_for_unsafe_access(); |
378 stub = StubRoutines::handler_for_unsafe_access(); |
379 } |
379 } |
404 } |
404 } |
405 } |
405 } |
406 else if (sig == SIGSEGV && |
406 else if (sig == SIGSEGV && |
407 !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { |
407 !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { |
408 // Determination of interpreter/vtable stub/compiled code null exception |
408 // Determination of interpreter/vtable stub/compiled code null exception |
409 #ifndef PRODUCT |
409 #ifdef PRINT_SIGNAL_HANDLE |
410 tty->print("continuation for implicit exception\n"); |
410 tty->print("continuation for implicit exception\n"); |
411 #endif |
411 #endif |
412 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); |
412 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); |
413 } |
413 } |
414 } else if (thread->thread_state() == _thread_in_vm && |
414 } else if (thread->thread_state() == _thread_in_vm && |
415 sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ |
415 sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ |
416 thread->doing_unsafe_access()) { |
416 thread->doing_unsafe_access()) { |
417 #ifndef PRODUCT |
417 #ifdef PRINT_SIGNAL_HANDLE |
418 tty->print_cr("SIGBUS in vm thread \n"); |
418 tty->print_cr("SIGBUS in vm thread \n"); |
419 #endif |
419 #endif |
420 stub = StubRoutines::handler_for_unsafe_access(); |
420 stub = StubRoutines::handler_for_unsafe_access(); |
421 } |
421 } |
422 |
422 |
423 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in |
423 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in |
424 // and the heap gets shrunk before the field access. |
424 // and the heap gets shrunk before the field access. |
425 if ((sig == SIGSEGV) || (sig == SIGBUS)) { |
425 if ((sig == SIGSEGV) || (sig == SIGBUS)) { |
426 #ifndef PRODUCT |
426 #ifdef PRINT_SIGNAL_HANDLE |
427 //tty->print("jni fast get trap: "); |
427 //tty->print("jni fast get trap: "); |
428 #endif |
428 #endif |
429 address addr = JNI_FastGetField::find_slowcase_pc(pc); |
429 address addr = JNI_FastGetField::find_slowcase_pc(pc); |
430 if (addr != (address)-1) { |
430 if (addr != (address)-1) { |
431 stub = addr; |
431 stub = addr; |
432 } |
432 } |
433 #ifndef PRODUCT |
433 #ifdef PRINT_SIGNAL_HANDLE |
434 //tty->print_cr("addr = %d, stub = %lx", addr, stub); |
434 //tty->print_cr("addr = %d, stub = %lx", addr, stub); |
435 #endif |
435 #endif |
436 } |
436 } |
437 |
437 |
438 // Check to see if we caught the safepoint code in the |
438 // Check to see if we caught the safepoint code in the |
440 // It write enables the page immediately after protecting it |
440 // It write enables the page immediately after protecting it |
441 // so we can just return to retry the write. |
441 // so we can just return to retry the write. |
442 if ((sig == SIGSEGV) && |
442 if ((sig == SIGSEGV) && |
443 os::is_memory_serialize_page(thread, (address) info->si_addr)) { |
443 os::is_memory_serialize_page(thread, (address) info->si_addr)) { |
444 // Block current thread until the memory serialize page permission restored. |
444 // Block current thread until the memory serialize page permission restored. |
445 #ifndef PRODUCT |
445 #ifdef PRINT_SIGNAL_HANDLE |
446 //tty->print("write protecting the memory serialiazation page\n"); |
446 //tty->print("write protecting the memory serialiazation page\n"); |
447 #endif |
447 #endif |
448 os::block_on_serialize_page_trap(); |
448 os::block_on_serialize_page_trap(); |
449 return true; |
449 return true; |
450 } |
450 } |
469 #endif |
469 #endif |
470 ) && |
470 ) && |
471 //(uc->uc_mcontext.cause == 2 || uc->uc_mcontext.cause == 3)) { |
471 //(uc->uc_mcontext.cause == 2 || uc->uc_mcontext.cause == 3)) { |
472 (uc->uc_mcontext.hi1 == 2 || uc->uc_mcontext.hi1 == 3)) { |
472 (uc->uc_mcontext.hi1 == 2 || uc->uc_mcontext.hi1 == 3)) { |
473 //aoqi: copy from jdk1.5, dont understand the struct mcontext_t. |
473 //aoqi: copy from jdk1.5, dont understand the struct mcontext_t. |
474 #ifndef PRODUCT |
474 #ifdef PRINT_SIGNAL_HANDLE |
475 tty->print_cr("execution protection violation\n"); |
475 tty->print_cr("execution protection violation\n"); |
476 #endif |
476 #endif |
477 |
477 |
478 int page_size = os::vm_page_size(); |
478 int page_size = os::vm_page_size(); |
479 address addr = (address) info->si_addr; |
479 address addr = (address) info->si_addr; |
550 return true; |
550 return true; |
551 } |
551 } |
552 |
552 |
553 // signal-chaining |
553 // signal-chaining |
554 if (os::Linux::chained_handler(sig, info, ucVoid)) { |
554 if (os::Linux::chained_handler(sig, info, ucVoid)) { |
555 #ifndef PRODUCT |
555 #ifdef PRINT_SIGNAL_HANDLE |
556 tty->print_cr("signal chaining\n"); |
556 tty->print_cr("signal chaining\n"); |
557 #endif |
557 #endif |
558 return true; |
558 return true; |
559 } |
559 } |
560 |
560 |
561 if (!abort_if_unrecognized) { |
561 if (!abort_if_unrecognized) { |
562 // caller wants another chance, so give it to him |
562 // caller wants another chance, so give it to him |
563 #ifndef PRODUCT |
563 #ifdef PRINT_SIGNAL_HANDLE |
564 tty->print_cr("abort becauce of unrecognized\n"); |
564 tty->print_cr("abort becauce of unrecognized\n"); |
565 #endif |
565 #endif |
566 return false; |
566 return false; |
567 } |
567 } |
568 |
568 |
573 // unmask current signal |
573 // unmask current signal |
574 sigset_t newset; |
574 sigset_t newset; |
575 sigemptyset(&newset); |
575 sigemptyset(&newset); |
576 sigaddset(&newset, sig); |
576 sigaddset(&newset, sig); |
577 sigprocmask(SIG_UNBLOCK, &newset, NULL); |
577 sigprocmask(SIG_UNBLOCK, &newset, NULL); |
578 #ifndef PRODUCT |
578 #ifdef PRINT_SIGNAL_HANDLE |
579 tty->print_cr("VMError in signal handler\n"); |
579 tty->print_cr("VMError in signal handler\n"); |
580 #endif |
580 #endif |
581 VMError err(t, sig, pc, info, ucVoid); |
581 VMError err(t, sig, pc, info, ucVoid); |
582 err.report_and_die(); |
582 err.report_and_die(); |
583 |
583 |