Unmatched LoadLibrary() call inside __crtMessageBoxX() functions - by Dmitry Me

Status : 


Sign in
to vote
ID 778455 Comments
Status Active Workarounds
Type Bug Repros 0
Opened 2/4/2013 5:29:12 AM
Access Restriction Public


Here's the code:

char* ptr = (char*)malloc(0);
memset( ptr, 0, 1000 );

When free() runs in Debug configuration I get a CRT debug error message about heap corruption. When I inspect the call stack I find myself inside crtmbox.c with this function:

#ifdef _UNICODE
int __cdecl __crtMessageBoxW(
#else  /* _UNICODE */
int __cdecl __crtMessageBoxA(
#endif  /* _UNICODE */

which has this code:

HMODULE hlib=LoadLibrary(_T("USER32.DLL"));

the problem is there's no matching FreeLibrary() anywhere. So for each load/unload of Visual C++ runtime the process will potentially increase the load count of user32.dll
Sign in to post a comment.
Posted by Dmitry Me on 2/7/2013 at 4:48 AM
Nope, Pat, you just didn't get what I was trying to say. All that is indeed fine when the VC++ runtime is linked to a .exe.

Now suppose it is linked to a .dll. Let it be MySample.dll Some executable loads MySample.dll, that loads VC++ runtime and once control first passes through __crtMessageBoxX() user32.dll is loaded. Then the executable unloads MySample.dll, VC++ runtime gets unloaded but user32.dll is not unloaded. The executable loads MySample.dll again, VC++ runtime is loaded again, its state is now as if it was loaded for the first time, so next time control passes through __crtMessageBoxX() user32.dll is loaded once again. This sequence will load user32.dll multiple times but never unload it. Very unlikely, but the bug will be extremely hard to reproduce.

The solution is not to unload user32.dll when __crtMessageBoxX() exits. The solution is to unload user32.dll when VC++ runtime unloads.
Posted by Microsoft on 2/5/2013 at 1:45 PM
Hello Dmitry,

Thanks for the report. I have investigated and found that this is by design. The USER32 DLL is not unloaded because function pointers are encoded and kept for later use in subsequent calls to the function. So the DLL is not loaded multiple times--it is loaded once in order to get the function pointers, and it is not unloaded because the function pointers may be called later. When the process unloads, the DLL will be unloaded--we don't want it to unload previous to that.

Pat Brenner
Visual C++ Libraries Development
Posted by Microsoft on 2/4/2013 at 11:20 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by Microsoft on 2/4/2013 at 5:52 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)