FreeLibrary vs implicit unloading DLL
I have implemented a DLL including DllMain() entry function:-
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
case DLL_PROCESS_ATTACH:
/* here im doing file memory mapped through CreateFileMapping() API
and using it through MapViewOfFile() API
storing some data structure in the file mapped area */
...
case DLL_THREAD_ATTACH:
...
case DLL_THREAD_DETACH:
...
case DLL_PROCESS_DETACH:
/* Here unmapping first through UnmapViewOfFile() API
then tries to access the stroed data structure which is illegal
as we have already closed the file mapping
This is the buggy code. The order should be first access the mapped memory
region and then unmap it */
cout <<" some message"<<endl;
...
}
Unfortunately i made a mistake in DLL_PROCESS_DETACH case and accessing illegal memorey (access violation).
I made a sample program which loads the library using LoadLibrary() function, uses the library function and finally call FreeLibrary() and return.
When i executed this program, i didnt get any error message. But if i remove FreeLibrary(), in that case the DLL_PROCESS_DETACH case is executed implicitly and this time it gives error dialog box mentioning that there is access violation.
Why calling FreeLibrary() suppress this error? OR internally it handles this exception? What is suggested way.
Update: I have added details for ATTACH and DETACH. Probably it will help why i am not clear about the behavior observed. With 开发者_如何学JAVAFreeLibrary() call, i didnt get any error message but the cout message was not displayed. It seems crashed too but not being bnotified. But if i remove FreeLibrary(), in that case the DLL_PROCESS_DETACH case is executed implicitly and gives access violation dialog box. Ideally in former case as well, it should display the error. So i am guessing the FreeLibrary() suppresses this access violation error.
The MSDN page for DllMain has a quote that might help explain what is happening to you.
When handling DLL_PROCESS_DETACH, a DLL should free resources such as heap memory only if the DLL is being unloaded dynamically (the lpReserved parameter is NULL). If the process is terminating (the lpvReserved parameter is non-NULL), all threads in the process except the current thread either have exited already or have been explicitly terminated by a call to the ExitProcess function, which might leave some process resources such as heaps in an inconsistent state. In this case, it is not safe for the DLL to clean up the resources. Instead, the DLL should allow the operating system to reclaim the memory.
So if you are calling FreeLibrary it's essentially a clean shutdown. Everything is in a valid state still. Any threads the Dll created are still around. All its memory is still around.
But if you just close the program (and don't call FreeLibrary) then it's more like an emergency shutdown (think crashing). Your Dll gets notified by the OS rather than the app. If this is the result of a crash then hoping memory is still valid isn't a great idea. And the stack is gone anyway.
So my guess is you are running into this problem because non-freed libraries are unloaded differently.
At the time of calling FreeLibrary, other parts of your program were all mapped into your virtual memory space. If your dll was freed automatically after other parts of your program had already been shut down, then fewer parts of your program were still mapped into your virtual memory space.
So at the time you called FreeLibrary, your bug in the DLL_PROCESS_DETACH case probably accessed memory that was in use by some other part of your program.
精彩评论