2338 jint MxCsr = INITIAL_MXCSR;
2339 // we can't use StubRoutines::addr_mxcsr_std()
2340 // because in Win64 mxcsr is not saved there
2341 if (MxCsr != ctx->MxCsr) {
2342 ctx->MxCsr = MxCsr;
2343 return EXCEPTION_CONTINUE_EXECUTION;
2344 }
2345 #endif // !_WIN64
2346
2347 return EXCEPTION_CONTINUE_SEARCH;
2348 }
2349
2350 static inline void report_error(Thread* t, DWORD exception_code,
2351 address addr, void* siginfo, void* context) {
2352 VMError::report_and_die(t, exception_code, addr, siginfo, context);
2353
2354 // If UseOsErrorReporting, this will return here and save the error file
2355 // somewhere where we can find it in the minidump.
2356 }
2357
2358 //-----------------------------------------------------------------------------
2359 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2360 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2361 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2362 #ifdef _M_IA64
2363 // On Itanium, we need the "precise pc", which has the slot number coded
2364 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2365 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2366 // Convert the pc to "Unix format", which has the slot number coded
2367 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2368 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2369 // information is saved in the Unix format.
2370 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2371 #else
2372 #ifdef _M_AMD64
2373 address pc = (address) exceptionInfo->ContextRecord->Rip;
2374 #else
2375 address pc = (address) exceptionInfo->ContextRecord->Eip;
2376 #endif
2377 #endif
2514 // Give us some room to process the exception.
2515 thread->disable_register_stack_guard();
2516 // Tracing with +Verbose.
2517 if (Verbose) {
2518 tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
2519 tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
2520 tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
2521 tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
2522 thread->register_stack_base(),
2523 thread->register_stack_base() + thread->stack_size());
2524 }
2525
2526 // Reguard the permanent register stack red zone just to be sure.
2527 // We saw Windows silently disabling this without telling us.
2528 thread->enable_register_stack_red_zone();
2529
2530 return Handle_Exception(exceptionInfo,
2531 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2532 }
2533 #endif
2534 if (thread->stack_yellow_zone_enabled()) {
2535 // Yellow zone violation. The o/s has unprotected the first yellow
2536 // zone page for us. Note: must call disable_stack_yellow_zone to
2537 // update the enabled status, even if the zone contains only one page.
2538 thread->disable_stack_yellow_zone();
2539 // If not in java code, return and hope for the best.
2540 return in_java
2541 ? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
2542 : EXCEPTION_CONTINUE_EXECUTION;
2543 } else {
2544 // Fatal red zone violation.
2545 thread->disable_stack_red_zone();
2546 tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
2547 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2548 exceptionInfo->ContextRecord);
2549 return EXCEPTION_CONTINUE_SEARCH;
2550 }
2551 } else if (in_java) {
2552 // JVM-managed guard pages cannot be used on win95/98. The o/s provides
2553 // a one-time-only guard page, which it has released to us. The next
2554 // stack overflow on this thread will result in an ACCESS_VIOLATION.
|
2338 jint MxCsr = INITIAL_MXCSR;
2339 // we can't use StubRoutines::addr_mxcsr_std()
2340 // because in Win64 mxcsr is not saved there
2341 if (MxCsr != ctx->MxCsr) {
2342 ctx->MxCsr = MxCsr;
2343 return EXCEPTION_CONTINUE_EXECUTION;
2344 }
2345 #endif // !_WIN64
2346
2347 return EXCEPTION_CONTINUE_SEARCH;
2348 }
2349
2350 static inline void report_error(Thread* t, DWORD exception_code,
2351 address addr, void* siginfo, void* context) {
2352 VMError::report_and_die(t, exception_code, addr, siginfo, context);
2353
2354 // If UseOsErrorReporting, this will return here and save the error file
2355 // somewhere where we can find it in the minidump.
2356 }
2357
2358 bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
2359 struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
2360 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2361 address addr = (address) exceptionRecord->ExceptionInformation[1];
2362 if (Interpreter::contains(pc)) {
2363 *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
2364 if (!fr->is_first_java_frame()) {
2365 assert(fr->safe_for_sender(thread), "Safety check");
2366 *fr = fr->java_sender();
2367 }
2368 } else {
2369 // more complex code with compiled code
2370 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
2371 CodeBlob* cb = CodeCache::find_blob(pc);
2372 if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
2373 // Not sure where the pc points to, fallback to default
2374 // stack overflow handling
2375 return false;
2376 } else {
2377 *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
2378 // in compiled code, the stack banging is performed just after the return pc
2379 // has been pushed on the stack
2380 *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
2381 if (!fr->is_java_frame()) {
2382 assert(fr->safe_for_sender(thread), "Safety check");
2383 *fr = fr->java_sender();
2384 }
2385 }
2386 }
2387 assert(fr->is_java_frame(), "Safety check");
2388 return true;
2389 }
2390
2391 //-----------------------------------------------------------------------------
2392 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2393 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2394 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2395 #ifdef _M_IA64
2396 // On Itanium, we need the "precise pc", which has the slot number coded
2397 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2398 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2399 // Convert the pc to "Unix format", which has the slot number coded
2400 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2401 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2402 // information is saved in the Unix format.
2403 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2404 #else
2405 #ifdef _M_AMD64
2406 address pc = (address) exceptionInfo->ContextRecord->Rip;
2407 #else
2408 address pc = (address) exceptionInfo->ContextRecord->Eip;
2409 #endif
2410 #endif
2547 // Give us some room to process the exception.
2548 thread->disable_register_stack_guard();
2549 // Tracing with +Verbose.
2550 if (Verbose) {
2551 tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
2552 tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
2553 tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
2554 tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
2555 thread->register_stack_base(),
2556 thread->register_stack_base() + thread->stack_size());
2557 }
2558
2559 // Reguard the permanent register stack red zone just to be sure.
2560 // We saw Windows silently disabling this without telling us.
2561 thread->enable_register_stack_red_zone();
2562
2563 return Handle_Exception(exceptionInfo,
2564 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2565 }
2566 #endif
2567 if (thread->stack_guards_enabled()) {
2568 if (_thread_in_Java) {
2569 frame fr;
2570 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2571 address addr = (address) exceptionRecord->ExceptionInformation[1];
2572 if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) {
2573 assert(fr.is_java_frame(), "Must be a Java frame");
2574 SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
2575 }
2576 }
2577 // Yellow zone violation. The o/s has unprotected the first yellow
2578 // zone page for us. Note: must call disable_stack_yellow_zone to
2579 // update the enabled status, even if the zone contains only one page.
2580 thread->disable_stack_yellow_zone();
2581 // If not in java code, return and hope for the best.
2582 return in_java
2583 ? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
2584 : EXCEPTION_CONTINUE_EXECUTION;
2585 } else {
2586 // Fatal red zone violation.
2587 thread->disable_stack_red_zone();
2588 tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
2589 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2590 exceptionInfo->ContextRecord);
2591 return EXCEPTION_CONTINUE_SEARCH;
2592 }
2593 } else if (in_java) {
2594 // JVM-managed guard pages cannot be used on win95/98. The o/s provides
2595 // a one-time-only guard page, which it has released to us. The next
2596 // stack overflow on this thread will result in an ACCESS_VIOLATION.
|