5256 } else { |
5256 } else { |
5257 return -1; |
5257 return -1; |
5258 } |
5258 } |
5259 } |
5259 } |
5260 |
5260 |
5261 //-------------------------------------------------------------------------------------------------- |
|
5262 // Non-product code |
|
5263 |
|
5264 static int mallocDebugIntervalCounter = 0; |
|
5265 static int mallocDebugCounter = 0; |
|
5266 |
|
5267 // For debugging possible bugs inside HeapWalk (a ring buffer) |
|
5268 #define SAVE_COUNT 8 |
|
5269 static PROCESS_HEAP_ENTRY saved_heap_entries[SAVE_COUNT]; |
|
5270 static int saved_heap_entry_index; |
|
5271 |
|
5272 bool os::check_heap(bool force) { |
|
5273 if (++mallocDebugCounter < MallocVerifyStart && !force) return true; |
|
5274 if (++mallocDebugIntervalCounter >= MallocVerifyInterval || force) { |
|
5275 // Note: HeapValidate executes two hardware breakpoints when it finds something |
|
5276 // wrong; at these points, eax contains the address of the offending block (I think). |
|
5277 // To get to the exlicit error message(s) below, just continue twice. |
|
5278 // |
|
5279 // Note: we want to check the CRT heap, which is not necessarily located in the |
|
5280 // process default heap. |
|
5281 HANDLE heap = (HANDLE) _get_heap_handle(); |
|
5282 if (!heap) { |
|
5283 return true; |
|
5284 } |
|
5285 |
|
5286 // If we fail to lock the heap, then gflags.exe has been used |
|
5287 // or some other special heap flag has been set that prevents |
|
5288 // locking. We don't try to walk a heap we can't lock. |
|
5289 if (HeapLock(heap) != 0) { |
|
5290 PROCESS_HEAP_ENTRY phe; |
|
5291 phe.lpData = NULL; |
|
5292 memset(saved_heap_entries, 0, sizeof(saved_heap_entries)); |
|
5293 saved_heap_entry_index = 0; |
|
5294 int count = 0; |
|
5295 |
|
5296 while (HeapWalk(heap, &phe) != 0) { |
|
5297 count ++; |
|
5298 if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) && |
|
5299 !HeapValidate(heap, 0, phe.lpData)) { |
|
5300 tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter); |
|
5301 tty->print_cr("corrupted block near address %#x, length %d, count %d", phe.lpData, phe.cbData, count); |
|
5302 HeapUnlock(heap); |
|
5303 fatal("corrupted C heap"); |
|
5304 } else { |
|
5305 // Save previous seen entries in a ring buffer. We have seen strange |
|
5306 // heap corruption fatal errors that produced mdmp files, but when we load |
|
5307 // these mdmp files in WinDBG, "!heap -triage" shows no error. |
|
5308 // We can examine the saved_heap_entries[] array in the mdmp file to |
|
5309 // diagnose such seemingly spurious errors reported by HeapWalk. |
|
5310 saved_heap_entries[saved_heap_entry_index++] = phe; |
|
5311 if (saved_heap_entry_index >= SAVE_COUNT) { |
|
5312 saved_heap_entry_index = 0; |
|
5313 } |
|
5314 } |
|
5315 } |
|
5316 DWORD err = GetLastError(); |
|
5317 if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED && |
|
5318 (err == ERROR_INVALID_FUNCTION && phe.lpData != NULL)) { |
|
5319 HeapUnlock(heap); |
|
5320 fatal("heap walk aborted with error %d", err); |
|
5321 } |
|
5322 HeapUnlock(heap); |
|
5323 } |
|
5324 mallocDebugIntervalCounter = 0; |
|
5325 } |
|
5326 return true; |
|
5327 } |
|
5328 |
|
5329 |
|
5330 bool os::find(address addr, outputStream* st) { |
5261 bool os::find(address addr, outputStream* st) { |
5331 int offset = -1; |
5262 int offset = -1; |
5332 bool result = false; |
5263 bool result = false; |
5333 char buf[256]; |
5264 char buf[256]; |
5334 if (os::dll_address_to_library_name(addr, buf, sizeof(buf), &offset)) { |
5265 if (os::dll_address_to_library_name(addr, buf, sizeof(buf), &offset)) { |