src/os_cpu/linux_mips/vm/os_linux_mips.cpp

changeset 181
721d96d20be1
parent 179
e67dc9f1ba90
child 182
d150daa954c4
equal deleted inserted replaced
180:5616e477f016 181:721d96d20be1
218 extern "C" int 218 extern "C" int
219 JVM_handle_linux_signal(int sig, 219 JVM_handle_linux_signal(int sig,
220 siginfo_t* info, 220 siginfo_t* info,
221 void* ucVoid, 221 void* ucVoid,
222 int abort_if_unrecognized) { 222 int abort_if_unrecognized) {
223 #ifndef PRODUCT 223 #ifdef PRINT_SIGNAL_HANDLE
224 tty->print_cr("Signal: signo=%d, sicode=%d, sierrno=%d, siaddr=%lx", 224 tty->print_cr("Signal: signo=%d, sicode=%d, sierrno=%d, siaddr=%lx",
225 info->si_signo, 225 info->si_signo,
226 info->si_code, 226 info->si_code,
227 info->si_errno, 227 info->si_errno,
228 info->si_addr); 228 info->si_addr);
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;
538 } 538 }
539 } 539 }
540 } 540 }
541 541
542 if (stub != NULL) { 542 if (stub != NULL) {
543 #ifndef PRODUCT 543 #ifdef PRINT_SIGNAL_HANDLE
544 //tty->print_cr("resolved stub=%lx\n",stub); 544 //tty->print_cr("resolved stub=%lx\n",stub);
545 #endif 545 #endif
546 // save all thread context in case we need to restore it 546 // save all thread context in case we need to restore it
547 if (thread != NULL) thread->set_saved_exception_pc(pc); 547 if (thread != NULL) thread->set_saved_exception_pc(pc);
548 548
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

mercurial