Memory problems with Windows VCR library
Posted on 2006-03-27
First: I am using Microsoft Visual Studio 2005 with debugging libraries turned on, on a Windows XP installation.
I have problems with the debug versions of the memory functions, namely _malloc_dbg and co. The first time I got this problem was when _malloc_dbg returned NULL on a request. That time I traced it back to a stack overflow created through the WndProc with a recursive SendMessage (yes it was a bug). The problem was that I didn't get a stack overflow error. Why is that?
After that it got worse. When I solved that I stumbled upon a second instance when _malloc_dbg returned NULL. That time I found this in the output log (*** is the app name):
First-chance exception at 0x7c926a36 (ntdll.dll) in ***.exe: 0xC0000005: Access violation writing location 0x454d4545.
First-chance exception at 0x7c910f29 (ntdll.dll) in ***.exe: 0xC0000005: Access violation reading location 0x454d4545.
First-chance exception at 0x7c91b3fb (ntdll.dll) in ***.exe: 0xC0000005: Access violation reading location 0x454d4545.
The stack frames for the first write violation (I am too tired to trace the second and third; they didn't seem that important because I though that if the first was solved, the rest would follow) show as:
ntdll.dll!_RtlFreeHeapSlowly@12() + 0x17f bytes
ntdll.dll!_RtlDebugFreeHeap@12() + 0x193 bytes
ntdll.dll!_RtlFreeHeapSlowly@12() + 0x23d19 bytes
ntdll.dll!_RtlFreeHeap@12() + 0x16470 bytes
msvcr80d.dll!_free_base(void * pBlock=0x009e3fe0) Line 109 + 0x13 bytes C
msvcr80d.dll!_free_dbg_nolock(void * pUserData=0x009e4000, int nBlockUse=1) Line 1329 + 0x9 bytes C++
msvcr80d.dll!_free_dbg(void * pUserData=0x009e4000, int nBlockUse=1) Line 1194 + 0xd bytes C++
***.exe!dbg_safe_free(void * _Memory=0x009e4000, int _BlockType=1) Line 84 + 0x10 bytes C
***.exe!AppWindowWmRequestUpdate(tagREQUESTUPDATE * lpUpdate=0x009e3fb8) Line 2135 + 0xe bytes C
***.exe!AppWindowWndProc(HWND__ * hWnd=0x007302f6, unsigned int uMsg=1025, unsigned int wParam=0, long lParam=10371000) Line 385 + 0x9 bytes C
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 bytes
***.exe!AppWindowMsgLoop() Line 280 + 0x12 bytes C
***.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f2c, int nCmdShow=1) Line 50 + 0x5 bytes C
***.exe!__tmainCRTStartup() Line 578 + 0x35 bytes C
***.exe!WinMainCRTStartup() Line 403 C
kernel32.dll!_BaseProcessStart@4() + 0x23 bytes
I traced the value 0x454d454d back to the value of pHead->pBlockHeaderNext->pBlockHeaderPrev at dbgheap.c:1329, but that's a guess. It could very well be that 0x454d454d is a generic dead fill that just happened to be at that location.
What's really neat of this is that _free_dbg has a try / catch so that these errors don't actually throw exceptions (that I can see), so that makes it just that much harder to catch this.
Now here we go. I only get this error when I turn on a specific part of the code which is in a secondary thread. It has two modes of operation (an offline for testing and online for retail, but still debug). The notable difference between the offline and retail mode is that the retail mode accesses the internet through libCURL. Now, I've checked this code like a hundred times (it's not that complicated) and I can't find any problems there.
My guess is then that it isn't there, but that's the only thing that changes; how could it be something else?
One last thing. I get the first access error when I free some memory in the main thread allocated in the secondary thread (which isn't in the mentioned block but is also located in the offline version and doesn't throw this error in that instance) and I get the NULL from _malloc_dbg after 6 new message on my WndProc.
I suspect this to be a stack overflow (or corruption) too but I don't know how to test for this.
If ANYBODY has ANY ideas, please throw them at me. I am at a total loss.