149 150 bool os::getenv(const char* name, char* buffer, int len) { 151 int result = GetEnvironmentVariable(name, buffer, len); 152 return result > 0 && result < len; 153 } 154 155 156 // No setuid programs under Windows. 157 bool os::have_special_privileges() { 158 return false; 159 } 160 161 162 // This method is a periodic task to check for misbehaving JNI applications 163 // under CheckJNI, we can add any periodic checks here. 164 // For Windows at the moment does nothing 165 void os::run_periodic_checks() { 166 return; 167 } 168 169 #ifndef _WIN64 170 // previous UnhandledExceptionFilter, if there is one 171 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL; 172 173 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); 174 #endif 175 void os::init_system_properties_values() { 176 /* sysclasspath, java_home, dll_dir */ 177 { 178 char *home_path; 179 char *dll_path; 180 char *pslash; 181 char *bin = "\\bin"; 182 char home_dir[MAX_PATH]; 183 184 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { 185 os::jvm_path(home_dir, sizeof(home_dir)); 186 // Found the full path to jvm.dll. 187 // Now cut the path to <java_home>/jre if we can. 188 *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ 189 pslash = strrchr(home_dir, '\\'); 190 if (pslash != NULL) { 191 *pslash = '\0'; /* get rid of \{client|server} */ 192 pslash = strrchr(home_dir, '\\'); 193 if (pslash != NULL) 194 *pslash = '\0'; /* get rid of \bin */ 2223 // set correct result values and continue after idiv instruction 2224 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes 2225 ctx->Rax = (DWORD)min_jint; // result 2226 ctx->Rdx = (DWORD)0; // remainder 2227 // Continue the execution 2228 #else 2229 PCONTEXT ctx = exceptionInfo->ContextRecord; 2230 address pc = (address)ctx->Eip; 2231 assert(pc[0] == 0xF7, "not an idiv opcode"); 2232 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); 2233 assert(ctx->Eax == min_jint, "unexpected idiv exception"); 2234 // set correct result values and continue after idiv instruction 2235 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes 2236 ctx->Eax = (DWORD)min_jint; // result 2237 ctx->Edx = (DWORD)0; // remainder 2238 // Continue the execution 2239 #endif 2240 return EXCEPTION_CONTINUE_EXECUTION; 2241 } 2242 2243 #ifndef _WIN64 2244 //----------------------------------------------------------------------------- 2245 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { 2246 // handle exception caused by native method modifying control word 2247 PCONTEXT ctx = exceptionInfo->ContextRecord; 2248 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; 2249 2250 switch (exception_code) { 2251 case EXCEPTION_FLT_DENORMAL_OPERAND: 2252 case EXCEPTION_FLT_DIVIDE_BY_ZERO: 2253 case EXCEPTION_FLT_INEXACT_RESULT: 2254 case EXCEPTION_FLT_INVALID_OPERATION: 2255 case EXCEPTION_FLT_OVERFLOW: 2256 case EXCEPTION_FLT_STACK_CHECK: 2257 case EXCEPTION_FLT_UNDERFLOW: 2258 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std()); 2259 if (fp_control_word != ctx->FloatSave.ControlWord) { 2260 // Restore FPCW and mask out FLT exceptions 2261 ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0; 2262 // Mask out pending FLT exceptions 2263 ctx->FloatSave.StatusWord &= 0xffffff00; 2264 return EXCEPTION_CONTINUE_EXECUTION; 2265 } 2266 } 2267 2268 if (prev_uef_handler != NULL) { 2269 // We didn't handle this exception so pass it to the previous 2270 // UnhandledExceptionFilter. 2271 return (prev_uef_handler)(exceptionInfo); 2272 } 2273 2274 return EXCEPTION_CONTINUE_SEARCH; 2275 } 2276 #else //_WIN64 2277 /* 2278 On Windows, the mxcsr control bits are non-volatile across calls 2279 See also CR 6192333 2280 If EXCEPTION_FLT_* happened after some native method modified 2281 mxcsr - it is not a jvm fault. 2282 However should we decide to restore of mxcsr after a faulty 2283 native method we can uncomment following code 2284 jint MxCsr = INITIAL_MXCSR; 2285 // we can't use StubRoutines::addr_mxcsr_std() 2286 // because in Win64 mxcsr is not saved there 2287 if (MxCsr != ctx->MxCsr) { 2288 ctx->MxCsr = MxCsr; 2289 return EXCEPTION_CONTINUE_EXECUTION; 2290 } 2291 2292 */ 2293 #endif //_WIN64 2294 2295 2296 // Fatal error reporting is single threaded so we can make this a 2297 // static and preallocated. If it's more than MAX_PATH silently ignore 2298 // it. 2299 static char saved_error_file[MAX_PATH] = {0}; 2300 2301 void os::set_error_file(const char *logfile) { 2302 if (strlen(logfile) <= MAX_PATH) { 2303 strncpy(saved_error_file, logfile, MAX_PATH); 2304 } 2305 } 2306 2307 static inline void report_error(Thread* t, DWORD exception_code, 2308 address addr, void* siginfo, void* context) { 2309 VMError err(t, exception_code, addr, siginfo, context); 2310 err.report_and_die(); 2311 2312 // If UseOsErrorReporting, this will return here and save the error file 2313 // somewhere where we can find it in the minidump. 2314 } 2623 // 2. must be a break instruction with appropriate code 2624 if((((uint64_t) pc & 0x0F) == 0) && 2625 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { 2626 return Handle_Exception(exceptionInfo, 2627 (address)SharedRuntime::get_handle_wrong_method_stub()); 2628 } 2629 } // /EXCEPTION_ILLEGAL_INSTRUCTION 2630 #endif 2631 2632 2633 if (in_java) { 2634 switch (exception_code) { 2635 case EXCEPTION_INT_DIVIDE_BY_ZERO: 2636 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); 2637 2638 case EXCEPTION_INT_OVERFLOW: 2639 return Handle_IDiv_Exception(exceptionInfo); 2640 2641 } // switch 2642 } 2643 #ifndef _WIN64 2644 if (((thread->thread_state() == _thread_in_Java) || 2645 (thread->thread_state() == _thread_in_native)) && 2646 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) 2647 { 2648 LONG result=Handle_FLT_Exception(exceptionInfo); 2649 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; 2650 } 2651 #endif //_WIN64 2652 } 2653 2654 if (exception_code != EXCEPTION_BREAKPOINT) { 2655 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, 2656 exceptionInfo->ContextRecord); 2657 } 2658 return EXCEPTION_CONTINUE_SEARCH; 2659 } 2660 2661 #ifndef _WIN64 2662 // Special care for fast JNI accessors. 2663 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and 2664 // the heap gets shrunk before the field access. 2665 // Need to install our own structured exception handler since native code may 2666 // install its own. 2667 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { 2668 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; 2669 if (exception_code == EXCEPTION_ACCESS_VIOLATION) { 2670 address pc = (address) exceptionInfo->ContextRecord->Eip; 2671 address addr = JNI_FastGetField::find_slowcase_pc(pc); | 149 150 bool os::getenv(const char* name, char* buffer, int len) { 151 int result = GetEnvironmentVariable(name, buffer, len); 152 return result > 0 && result < len; 153 } 154 155 156 // No setuid programs under Windows. 157 bool os::have_special_privileges() { 158 return false; 159 } 160 161 162 // This method is a periodic task to check for misbehaving JNI applications 163 // under CheckJNI, we can add any periodic checks here. 164 // For Windows at the moment does nothing 165 void os::run_periodic_checks() { 166 return; 167 } 168 169 // previous UnhandledExceptionFilter, if there is one 170 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL; 171 172 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); 173 void os::init_system_properties_values() { 174 /* sysclasspath, java_home, dll_dir */ 175 { 176 char *home_path; 177 char *dll_path; 178 char *pslash; 179 char *bin = "\\bin"; 180 char home_dir[MAX_PATH]; 181 182 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { 183 os::jvm_path(home_dir, sizeof(home_dir)); 184 // Found the full path to jvm.dll. 185 // Now cut the path to <java_home>/jre if we can. 186 *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ 187 pslash = strrchr(home_dir, '\\'); 188 if (pslash != NULL) { 189 *pslash = '\0'; /* get rid of \{client|server} */ 190 pslash = strrchr(home_dir, '\\'); 191 if (pslash != NULL) 192 *pslash = '\0'; /* get rid of \bin */ 2221 // set correct result values and continue after idiv instruction 2222 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes 2223 ctx->Rax = (DWORD)min_jint; // result 2224 ctx->Rdx = (DWORD)0; // remainder 2225 // Continue the execution 2226 #else 2227 PCONTEXT ctx = exceptionInfo->ContextRecord; 2228 address pc = (address)ctx->Eip; 2229 assert(pc[0] == 0xF7, "not an idiv opcode"); 2230 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); 2231 assert(ctx->Eax == min_jint, "unexpected idiv exception"); 2232 // set correct result values and continue after idiv instruction 2233 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes 2234 ctx->Eax = (DWORD)min_jint; // result 2235 ctx->Edx = (DWORD)0; // remainder 2236 // Continue the execution 2237 #endif 2238 return EXCEPTION_CONTINUE_EXECUTION; 2239 } 2240 2241 //----------------------------------------------------------------------------- 2242 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { 2243 #ifndef _WIN64 2244 // handle exception caused by native method modifying control word 2245 PCONTEXT ctx = exceptionInfo->ContextRecord; 2246 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; 2247 2248 switch (exception_code) { 2249 case EXCEPTION_FLT_DENORMAL_OPERAND: 2250 case EXCEPTION_FLT_DIVIDE_BY_ZERO: 2251 case EXCEPTION_FLT_INEXACT_RESULT: 2252 case EXCEPTION_FLT_INVALID_OPERATION: 2253 case EXCEPTION_FLT_OVERFLOW: 2254 case EXCEPTION_FLT_STACK_CHECK: 2255 case EXCEPTION_FLT_UNDERFLOW: 2256 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std()); 2257 if (fp_control_word != ctx->FloatSave.ControlWord) { 2258 // Restore FPCW and mask out FLT exceptions 2259 ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0; 2260 // Mask out pending FLT exceptions 2261 ctx->FloatSave.StatusWord &= 0xffffff00; 2262 return EXCEPTION_CONTINUE_EXECUTION; 2263 } 2264 } 2265 2266 if (prev_uef_handler != NULL) { 2267 // We didn't handle this exception so pass it to the previous 2268 // UnhandledExceptionFilter. 2269 return (prev_uef_handler)(exceptionInfo); 2270 } 2271 #else // !_WIN64 2272 /* 2273 On Windows, the mxcsr control bits are non-volatile across calls 2274 See also CR 6192333 2275 */ 2276 PCONTEXT ctx = exceptionInfo->ContextRecord; 2277 jint MxCsr = INITIAL_MXCSR; 2278 // we can't use StubRoutines::addr_mxcsr_std() 2279 // because in Win64 mxcsr is not saved there 2280 if (MxCsr != ctx->MxCsr) { 2281 ctx->MxCsr = MxCsr; 2282 return EXCEPTION_CONTINUE_EXECUTION; 2283 } 2284 #endif // !_WIN64 2285 2286 return EXCEPTION_CONTINUE_SEARCH; 2287 } 2288 2289 // Fatal error reporting is single threaded so we can make this a 2290 // static and preallocated. If it's more than MAX_PATH silently ignore 2291 // it. 2292 static char saved_error_file[MAX_PATH] = {0}; 2293 2294 void os::set_error_file(const char *logfile) { 2295 if (strlen(logfile) <= MAX_PATH) { 2296 strncpy(saved_error_file, logfile, MAX_PATH); 2297 } 2298 } 2299 2300 static inline void report_error(Thread* t, DWORD exception_code, 2301 address addr, void* siginfo, void* context) { 2302 VMError err(t, exception_code, addr, siginfo, context); 2303 err.report_and_die(); 2304 2305 // If UseOsErrorReporting, this will return here and save the error file 2306 // somewhere where we can find it in the minidump. 2307 } 2616 // 2. must be a break instruction with appropriate code 2617 if((((uint64_t) pc & 0x0F) == 0) && 2618 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { 2619 return Handle_Exception(exceptionInfo, 2620 (address)SharedRuntime::get_handle_wrong_method_stub()); 2621 } 2622 } // /EXCEPTION_ILLEGAL_INSTRUCTION 2623 #endif 2624 2625 2626 if (in_java) { 2627 switch (exception_code) { 2628 case EXCEPTION_INT_DIVIDE_BY_ZERO: 2629 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); 2630 2631 case EXCEPTION_INT_OVERFLOW: 2632 return Handle_IDiv_Exception(exceptionInfo); 2633 2634 } // switch 2635 } 2636 if (((thread->thread_state() == _thread_in_Java) || 2637 (thread->thread_state() == _thread_in_native)) && 2638 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) 2639 { 2640 LONG result=Handle_FLT_Exception(exceptionInfo); 2641 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; 2642 } 2643 } 2644 2645 if (exception_code != EXCEPTION_BREAKPOINT) { 2646 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, 2647 exceptionInfo->ContextRecord); 2648 } 2649 return EXCEPTION_CONTINUE_SEARCH; 2650 } 2651 2652 #ifndef _WIN64 2653 // Special care for fast JNI accessors. 2654 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and 2655 // the heap gets shrunk before the field access. 2656 // Need to install our own structured exception handler since native code may 2657 // install its own. 2658 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { 2659 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; 2660 if (exception_code == EXCEPTION_ACCESS_VIOLATION) { 2661 address pc = (address) exceptionInfo->ContextRecord->Eip; 2662 address addr = JNI_FastGetField::find_slowcase_pc(pc); |