93 #include <vdmdbg.h>
94
95 // for timer info max values which include all bits
96 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
97
98 // For DLL loading/load error detection
99 // Values of PE COFF
100 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
101 #define IMAGE_FILE_SIGNATURE_LENGTH 4
102
103 static HANDLE main_process;
104 static HANDLE main_thread;
105 static int main_thread_id;
106
107 static FILETIME process_creation_time;
108 static FILETIME process_exit_time;
109 static FILETIME process_user_time;
110 static FILETIME process_kernel_time;
111
112 #ifdef _M_IA64
113 #define __CPU__ ia64
114 #elif _M_AMD64
115 #define __CPU__ amd64
116 #else
117 #define __CPU__ i486
118 #endif
119
120 // save DLL module handle, used by GetModuleFileName
121
122 HINSTANCE vm_lib_handle;
123
124 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
125 switch (reason) {
126 case DLL_PROCESS_ATTACH:
127 vm_lib_handle = hinst;
128 if(ForceTimeHighResolution)
129 timeBeginPeriod(1L);
130 break;
131 case DLL_PROCESS_DETACH:
132 if(ForceTimeHighResolution)
133 timeEndPeriod(1L);
134
135 break;
136 default:
137 break;
2121 // Implicit OS exception handling
2122
2123 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
2124 JavaThread* thread = JavaThread::current();
2125 // Save pc in thread
2126 #ifdef _M_IA64
2127 // Do not blow up if no thread info available.
2128 if (thread) {
2129 // Saving PRECISE pc (with slot information) in thread.
2130 uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
2131 // Convert precise PC into "Unix" format
2132 precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
2133 thread->set_saved_exception_pc((address)precise_pc);
2134 }
2135 // Set pc to handler
2136 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
2137 // Clear out psr.ri (= Restart Instruction) in order to continue
2138 // at the beginning of the target bundle.
2139 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
2140 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
2141 #elif _M_AMD64
2142 // Do not blow up if no thread info available.
2143 if (thread) {
2144 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2145 }
2146 // Set pc to handler
2147 exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2148 #else
2149 // Do not blow up if no thread info available.
2150 if (thread) {
2151 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2152 }
2153 // Set pc to handler
2154 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
2155 #endif
2156
2157 // Continue the execution
2158 return EXCEPTION_CONTINUE_EXECUTION;
2159 }
2160
2161
2162 // Used for PostMortemDump
2163 extern "C" void safepoints();
2164 extern "C" void find(int x);
2165 extern "C" void events();
2166
2167 // According to Windows API documentation, an illegal instruction sequence should generate
2168 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2169 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2170 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2171
2172 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2173
2174 // From "Execution Protection in the Windows Operating System" draft 0.35
2233 NULL, 0
2234 };
2235
2236 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2237 for (int i = 0; exceptlabels[i].name != NULL; i++) {
2238 if (exceptlabels[i].number == exception_code) {
2239 jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2240 return buf;
2241 }
2242 }
2243
2244 return NULL;
2245 }
2246
2247 //-----------------------------------------------------------------------------
2248 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2249 // handle exception caused by idiv; should only happen for -MinInt/-1
2250 // (division by zero is handled explicitly)
2251 #ifdef _M_IA64
2252 assert(0, "Fix Handle_IDiv_Exception");
2253 #elif _M_AMD64
2254 PCONTEXT ctx = exceptionInfo->ContextRecord;
2255 address pc = (address)ctx->Rip;
2256 assert(pc[0] == 0xF7, "not an idiv opcode");
2257 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2258 assert(ctx->Rax == min_jint, "unexpected idiv exception");
2259 // set correct result values and continue after idiv instruction
2260 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes
2261 ctx->Rax = (DWORD)min_jint; // result
2262 ctx->Rdx = (DWORD)0; // remainder
2263 // Continue the execution
2264 #else
2265 PCONTEXT ctx = exceptionInfo->ContextRecord;
2266 address pc = (address)ctx->Eip;
2267 assert(pc[0] == 0xF7, "not an idiv opcode");
2268 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2269 assert(ctx->Eax == min_jint, "unexpected idiv exception");
2270 // set correct result values and continue after idiv instruction
2271 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes
2272 ctx->Eax = (DWORD)min_jint; // result
2273 ctx->Edx = (DWORD)0; // remainder
2274 // Continue the execution
2275 #endif
2276 return EXCEPTION_CONTINUE_EXECUTION;
2277 }
2278
2279 #ifndef _WIN64
2280 //-----------------------------------------------------------------------------
2281 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2282 // handle exception caused by native method modifying control word
2283 PCONTEXT ctx = exceptionInfo->ContextRecord;
2284 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2285
2286 switch (exception_code) {
2287 case EXCEPTION_FLT_DENORMAL_OPERAND:
2288 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2289 case EXCEPTION_FLT_INEXACT_RESULT:
2290 case EXCEPTION_FLT_INVALID_OPERATION:
2291 case EXCEPTION_FLT_OVERFLOW:
2292 case EXCEPTION_FLT_STACK_CHECK:
2293 case EXCEPTION_FLT_UNDERFLOW:
2294 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2334 VMError err(t, exception_code, addr, siginfo, context);
2335 err.report_and_die();
2336
2337 // If UseOsErrorReporting, this will return here and save the error file
2338 // somewhere where we can find it in the minidump.
2339 }
2340
2341 //-----------------------------------------------------------------------------
2342 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2343 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2344 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2345 #ifdef _M_IA64
2346 // On Itanium, we need the "precise pc", which has the slot number coded
2347 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2348 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2349 // Convert the pc to "Unix format", which has the slot number coded
2350 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2351 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2352 // information is saved in the Unix format.
2353 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2354 #elif _M_AMD64
2355 address pc = (address) exceptionInfo->ContextRecord->Rip;
2356 #else
2357 address pc = (address) exceptionInfo->ContextRecord->Eip;
2358 #endif
2359 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
2360
2361 // Handle SafeFetch32 and SafeFetchN exceptions.
2362 if (StubRoutines::is_safefetch_fault(pc)) {
2363 return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2364 }
2365
2366 #ifndef _WIN64
2367 // Execution protection violation - win32 running on AMD64 only
2368 // Handled first to avoid misdiagnosis as a "normal" access violation;
2369 // This is safe to do because we have a new/unique ExceptionInformation
2370 // code for this condition.
2371 if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2372 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2373 int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2374 address addr = (address) exceptionRecord->ExceptionInformation[1];
2375
2376 if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2377 int page_size = os::vm_page_size();
|
93 #include <vdmdbg.h>
94
95 // for timer info max values which include all bits
96 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
97
98 // For DLL loading/load error detection
99 // Values of PE COFF
100 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
101 #define IMAGE_FILE_SIGNATURE_LENGTH 4
102
103 static HANDLE main_process;
104 static HANDLE main_thread;
105 static int main_thread_id;
106
107 static FILETIME process_creation_time;
108 static FILETIME process_exit_time;
109 static FILETIME process_user_time;
110 static FILETIME process_kernel_time;
111
112 #ifdef _M_IA64
113 #define __CPU__ ia64
114 #else
115 #ifdef _M_AMD64
116 #define __CPU__ amd64
117 #else
118 #define __CPU__ i486
119 #endif
120 #endif
121
122 // save DLL module handle, used by GetModuleFileName
123
124 HINSTANCE vm_lib_handle;
125
126 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
127 switch (reason) {
128 case DLL_PROCESS_ATTACH:
129 vm_lib_handle = hinst;
130 if(ForceTimeHighResolution)
131 timeBeginPeriod(1L);
132 break;
133 case DLL_PROCESS_DETACH:
134 if(ForceTimeHighResolution)
135 timeEndPeriod(1L);
136
137 break;
138 default:
139 break;
2123 // Implicit OS exception handling
2124
2125 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
2126 JavaThread* thread = JavaThread::current();
2127 // Save pc in thread
2128 #ifdef _M_IA64
2129 // Do not blow up if no thread info available.
2130 if (thread) {
2131 // Saving PRECISE pc (with slot information) in thread.
2132 uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
2133 // Convert precise PC into "Unix" format
2134 precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
2135 thread->set_saved_exception_pc((address)precise_pc);
2136 }
2137 // Set pc to handler
2138 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
2139 // Clear out psr.ri (= Restart Instruction) in order to continue
2140 // at the beginning of the target bundle.
2141 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
2142 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
2143 #else
2144 #ifdef _M_AMD64
2145 // Do not blow up if no thread info available.
2146 if (thread) {
2147 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2148 }
2149 // Set pc to handler
2150 exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2151 #else
2152 // Do not blow up if no thread info available.
2153 if (thread) {
2154 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2155 }
2156 // Set pc to handler
2157 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
2158 #endif
2159 #endif
2160
2161 // Continue the execution
2162 return EXCEPTION_CONTINUE_EXECUTION;
2163 }
2164
2165
2166 // Used for PostMortemDump
2167 extern "C" void safepoints();
2168 extern "C" void find(int x);
2169 extern "C" void events();
2170
2171 // According to Windows API documentation, an illegal instruction sequence should generate
2172 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2173 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2174 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2175
2176 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2177
2178 // From "Execution Protection in the Windows Operating System" draft 0.35
2237 NULL, 0
2238 };
2239
2240 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2241 for (int i = 0; exceptlabels[i].name != NULL; i++) {
2242 if (exceptlabels[i].number == exception_code) {
2243 jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2244 return buf;
2245 }
2246 }
2247
2248 return NULL;
2249 }
2250
2251 //-----------------------------------------------------------------------------
2252 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2253 // handle exception caused by idiv; should only happen for -MinInt/-1
2254 // (division by zero is handled explicitly)
2255 #ifdef _M_IA64
2256 assert(0, "Fix Handle_IDiv_Exception");
2257 #else
2258 #ifdef _M_AMD64
2259 PCONTEXT ctx = exceptionInfo->ContextRecord;
2260 address pc = (address)ctx->Rip;
2261 assert(pc[0] == 0xF7, "not an idiv opcode");
2262 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2263 assert(ctx->Rax == min_jint, "unexpected idiv exception");
2264 // set correct result values and continue after idiv instruction
2265 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes
2266 ctx->Rax = (DWORD)min_jint; // result
2267 ctx->Rdx = (DWORD)0; // remainder
2268 // Continue the execution
2269 #else
2270 PCONTEXT ctx = exceptionInfo->ContextRecord;
2271 address pc = (address)ctx->Eip;
2272 assert(pc[0] == 0xF7, "not an idiv opcode");
2273 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2274 assert(ctx->Eax == min_jint, "unexpected idiv exception");
2275 // set correct result values and continue after idiv instruction
2276 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes
2277 ctx->Eax = (DWORD)min_jint; // result
2278 ctx->Edx = (DWORD)0; // remainder
2279 // Continue the execution
2280 #endif
2281 #endif
2282 return EXCEPTION_CONTINUE_EXECUTION;
2283 }
2284
2285 #ifndef _WIN64
2286 //-----------------------------------------------------------------------------
2287 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2288 // handle exception caused by native method modifying control word
2289 PCONTEXT ctx = exceptionInfo->ContextRecord;
2290 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2291
2292 switch (exception_code) {
2293 case EXCEPTION_FLT_DENORMAL_OPERAND:
2294 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2295 case EXCEPTION_FLT_INEXACT_RESULT:
2296 case EXCEPTION_FLT_INVALID_OPERATION:
2297 case EXCEPTION_FLT_OVERFLOW:
2298 case EXCEPTION_FLT_STACK_CHECK:
2299 case EXCEPTION_FLT_UNDERFLOW:
2300 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2340 VMError err(t, exception_code, addr, siginfo, context);
2341 err.report_and_die();
2342
2343 // If UseOsErrorReporting, this will return here and save the error file
2344 // somewhere where we can find it in the minidump.
2345 }
2346
2347 //-----------------------------------------------------------------------------
2348 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2349 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2350 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2351 #ifdef _M_IA64
2352 // On Itanium, we need the "precise pc", which has the slot number coded
2353 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2354 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2355 // Convert the pc to "Unix format", which has the slot number coded
2356 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2357 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2358 // information is saved in the Unix format.
2359 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2360 #else
2361 #ifdef _M_AMD64
2362 address pc = (address) exceptionInfo->ContextRecord->Rip;
2363 #else
2364 address pc = (address) exceptionInfo->ContextRecord->Eip;
2365 #endif
2366 #endif
2367 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
2368
2369 // Handle SafeFetch32 and SafeFetchN exceptions.
2370 if (StubRoutines::is_safefetch_fault(pc)) {
2371 return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2372 }
2373
2374 #ifndef _WIN64
2375 // Execution protection violation - win32 running on AMD64 only
2376 // Handled first to avoid misdiagnosis as a "normal" access violation;
2377 // This is safe to do because we have a new/unique ExceptionInformation
2378 // code for this condition.
2379 if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2380 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2381 int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2382 address addr = (address) exceptionRecord->ExceptionInformation[1];
2383
2384 if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2385 int page_size = os::vm_page_size();
|