So I have a DLL I wrote in C++.
However, it allocates memory using GlobalAlloc(). To avoid memory leaks, I want to keep track of these allocations and de-allocate all of them on the destruction of the DLL.
Is there any way to write a function that will be called when my DLL is unloaded?
One thing I can think of is creating a global object in my DLL and writing the memory free calls in its destructor, but this seems like overkill.
My other idea is to just rely on the operating system to free the memory when the DLL unloads, but this seems dirty.
Is there any way to write a function that will be called when my DLL is unloaded? One thing I can think of is creating a global object in my DLL and writing the memory free calls in its destructor
That's possible, although I believe exactly when your object's destructor will be called will be undefined.
You might be interested in DLL_PROCESS_DETACH, and although you should avoid doing anything significant in DllMain, it seems deallocating resources is acceptable here. Note the caveats:
When a DLL is unloaded from a process as a result of an unsuccessful load of the DLL, termination of the process, or a call to FreeLibrary, the system does not call the DLL's entry-point function with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only sent a DLL_PROCESS_DETACH notification. DLLs can take this opportunity to clean up all resources for all threads known to the DLL.
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.
You might need to elaborate on why your DLL can hold on to memory, if you have numerous objects created by the DLL, they should have a defined lifecycle and clean themselves up at the end of their life.
If they're not objects (i.e. memory being allocated and returned to the caller via functions) why not put the responsibility back onto whoever is consuming your DLL? They can free the memory. The Terminal Services library follows this pattern (WTSFreeMemory).
If the resources are long-lived and must exist for the lifetime of your library, let the consumer control the lifecycle of your library. Write two functions: MyFrameworkStartup and MyFrameworkShutdown as appropriate. Winsock follows this pattern (WSAStartup and WSACleanup).
My other idea is to just rely on the operating system to free the memory when the DLL unloads, but this seems dirty.
You'll be okay if the process is exiting:
Don't worry about freeing memory; it will all go away when the process address space is destroyed. Don't worry about closing handles; handles are closed automatically when the process handle table is destroyed. Don't try to call into other DLLs, because those other DLLs may already have received their DLL_PROCESS_DETACH notifications, in which case they may behave erratically in the same way that a Delphi object behaves erratically if you try to use it after its destructor has run.
Make sure you read the whole article and comments and understand it before implementing the "do nothing" strategy.
How/when is the memory allocated? Usually, the sanest option is to try to preserve some kind of symmetry (constructor allocates, destructor deallocates. Or memory allocated when DLL is loaded, and freed when DLL is unloaded).
In any case, if you want to be notified when the DLL is unloaded, look into the DllMain function, and specifically the DLL_PROCESS_DETACH parameter.
The DllMain function is called, with fdwReason set to DLL_PROCESS_DETACH, when a DLL is unloaded. As described in the documentation, make sure you check the value of lpvReserved and only free memory if it is NULL; you should not free memory if the process is terminating.
Related
I write a piece of test code in VS2005 like this:
#include <stdio.h>
class Base {
public:
Base() {printf("Base +\n");};
~Base() {printf("Base -\n");};
char val[1024 * 1024 * 100];
};
void main()
{
Base *p = new Base();
return;
}
build, open a cmd window, then execute this console application.
open windows task manager to watch memory usage status.
I find two things:
1 the destructor is not called;
2 there is no memory leak from the windows task manager result.
is memory deleted by C++ runtime, or is it deleted by OS when the process exit? I just wonder the details about what happens to 100MB meory allocated in contructor after the main() return. If someone can tell me it is appreciated, and thanks.
After your program exits, the operating system will reclaim all used memory, whether or not delete has been called on it.
Other resources, like sockets, might take longer to be released by the operating system, but will eventually be reclaimed.
It will be up to the operating system.
However, things that you thought would go away when the app goes away tend to stay in memory longer than you thought. At some point, the code in main is moved to some function that gets called once. And then that function gets called multiple times. And then you have a leak. Better coding defensively in the first place than to fix problems later. Maybe years later.
Destructor not get called because you are not deleting your class B pointer.
Also after your application exits all the allocated resources get released irrespective whether you released it or not.
As with other answer, it's up to the operating system.
Having said this, it's usually well documented what will be clean up upon program termination.
This usually include application's private memory, files, sockets, resource handles, GUI resources, and may exclude resources that is global or shared amount many applications. (e.g. POSIX shared memory will persist until reboot if you do not call shm_unlink).
I have a C++ app I'm developing in Linux. I'm allocating some dynamic memory and ultimately calling forkpty(). The child process is calling execl() and as we know, execl() never returns if it succeeds to execute the command. Furthermore, as we know, forkpty() makes a copy of all the parent's data. So, if the child() process never returns control back to my application in order to ultimately do memory cleanup, is it safe to say one better not have any dynamic memory allocated at the time execl() is called from the child process??? I can't believe I could not find this one on here... Thanks in advance.
Allocated memory is part of the process image; when you call
execl, the entire process image is replaced, and any memory in
it simply "disappears" like the rest of it, returning to the OS,
which will then use it elsewhere.
All of the "forked" process memory is freed as part of execl() (if the call is successful).
If this wasn't the case, there would be a lot of memory leaks all over a regular linux system, as it's almost impossible to write anything even a little complex without allocating memory, and, for example, if the arguments to execl() are allocated, you couldn't possibly free them before calling execl().
By using 'codecave' technique to inject code into another process; is it possible to inject code to create a new thread (and also inject the code for the new thread) and let that thread execute parallel with the target process main thread?
I can manage this with dll injection but I want to know if it is possible with just pure code injection.
The intention is first of all to learn about different injection techniques but in the end create a heartbeat feature for random processes in order to supervise execution (High Availability). Windows is the target OS and language is C/C++ (with inline ASM when required).
Thanks.
There is CreateRemoteThread function.
When using a DLL injection loader such as "Winject (the one that calls CreateRemoteThread) it is very easy to create Threads that remain until the target process closes.
Just create the Thread within the function:
void run_thread(void* ass)
{
// do stuff until process terminates
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD result, LPVOID lpReserved)
{
HANDLE handle = (HANDLE)_beginthread(run_thread, 0, 0);
}
regards,
michael
Sure, but you would have to also inject the code for the remote thread into the process (e.g. a function). Injecting an entire function into a remote process is a pain because there is no clear-cut way to determine the size of a function. This approach would be far more effective if the injected code was small, in which case you would just inject a short assembly stub, then call CreateRemoteThread.
Really though, what would be a benefit of doing this over just straight-up DLL injection? Your 'heartbeat' feature could be implemented just as easily with an injected DLL. (unless someone is going to tell me there's significant overhead?)
The problem is, even if you inject your code into the process, unless you create a thread at the start of your injected code, it will still not run. Typically, to do code injection you would inject a full DLL. One of popular ways of injecting DLLs is to:
Get a handle to the target process (EnumProcesses, CreateTool32Snapshot/Process32First/Process32Next, FindWindow/GetWindowThreadProcessId/OpenProcess, etc.)
Allocate memory in the target process that is the same length as a string pointing to the path of your DLL (VirtualAllocEx)
Write a string pointing to the path of your DLL to this allocated memory (WriteProcessMemory)
Create a remote thread at the LoadLibrary routine (get the address by GetModuleHandle/GetProcAddress) and pass the pointer to the allocated memory as a parameter (CreateRemoteThread)
Release the allocated memory (VirtualFreeEx)
Close any opened handles (process handles, snapshot handles, etc. with CloseHandle)
Unless there is a particular reason you want to avoid this method, it is by far preferable to copying in the code yourself (WriteProcessMemory and probably setting up page protections (VirtualProtectEx)). Without loading a library you will need to manually map variables, relocate function pointers and all the other work LoadLibrary does.
You asked earlier about the semantics of CreateRemoteThread. It will create a thread in another process which will keep going until it terminates itself or something else does (someone calls TerminateThread or the process terminates and calls ExitProcess, etc.). The thread will run as parallel in the same way a thread that was legitimately created would (context switching).
You can also use the RtlCreateUserThread function to create the remote thread.
I need to make use of thread-local storage in a cross-platform project. Under *IX I am using pthreads and can avoid memory leaks thanks to the nice destructor function pointer passed as the second argument to pthread_key_create, but in Windows TlsAlloc has no such thing. Nor can I find a general place where any function is called on thread exit (otherwise I would homebrew some list of function pointers that get called at exit).
As it stands it seems that I have basically a situation where in order to actually use thread local storage I need to allocate my own space on the heap and pass a pointer to TlsSetValue, but if the thread exits ... I have no way of ensuring the memory was freed (other than someone explicitly calling TlsGetValue and delete/free/HeapFree/etc at the end of the thread function.
Does anyone know of a better way?
You can get yourself a nice "finalizer" to get rid of thread-specific resources, even if the thread is terminated: use RegisterWaitForSingleObject to wait on a copy (via DuplicateHandle) of the threads' handle - you have to use the cloned handle, cause registered waits can't handle handle {no pun intended} closing.
Use a heap allocated structure/record to hold the finalized resources, the handle waited for and the wait handle itself, cause the finalizer will run in the system threadpool, NOT the finalized thread (which will be already dead by the time). And don't forget to finalize the finalizer :)
The entry point of a DLL (DLLmain) is called on thread exit with a reason code of DLL_THREAD_DETACH. It is fairly straightforward to write a DLL that keeps track of functions to call on thread exit.
Alternatively, use Boost.Thread and the boost::this_thread::at_thread_exit function to register a function to be called on thread exit, or use boost::thread_specific_ptr to wrap the TLS usage entirely.
How can I ensure a dll is not unloaded while any objects in it exist?
The problem is, when I was using explict memory management I could delete the dll objects before freeing the dll, however with smart pointers I have no controll over the order there destroyed, meaning the dll may be freed first causeing a crash when trying to free one of the other objects:
FlPtr is a simple refrence counting class thats calls AddRef and Release as needed
ExampleDll *dll = LoadDll(L"bin\\example.dll");
IObject *obj = dll->CreateObject();
...
obj->Release();
delete dll;//fine because all objects already deleted
return 0;
auto_ptr<ExampleDll> dll = LoadDll(L"bin\\example.dll");
FlPtr<IObject> obj = dll->CreateObject();
...
return 0;//crash if dll is destructed before obj since Object::Release needs to call into the dll
I tried making the dll handle unloading itsself, ie only unload after all objects have been deleted. This work by creating a new object IExampleDll which the dll implements. This is like the ExampleDll object from before but lives in the dll rather than the exe and is also refrence counted. Each object in the dll increments this refrence on contruction and deincrements it on destruction. This means the refrence count only reaches zero when the exe has Released its refrences AND all the dlls objects have been destroyed. It then deletes itsself calling FreeLibrary(GetModuleHandle()) in its destructor.
This however crashes at the FreeLibrary, im asuming because the thread is still in the dlls code that is being unloaded...
I'm at a loss now how to make sure the dll is only unloaded when there are no remaining objects, apart from going back to freeing the dll explicitly after everything else should have been deleted;
int main()
{
ExampleDll *dll = LoadDll("bin\\example.dll");
restOfProgram();
delete dll;
}
This approach becomes difficult when dlls need to be loaded/unloaded mid program saftly, ie if the user changed from d3d to openGL in options.
Assuming you do not want to terminate the thread when unloading the library (otherwise, see MSalters), you need to free the library from the caller that loaded it.
COM solves that by an in-DLL instance counter (much like yours, if I understand you correctly), and regulary checking it by calling a global exported CanUnloadNow function.
Another option is to have your object/interface smart pointers ALSO reference the DLL they came from. This would increase the client data size, but you wouldn't need to touch the DLL. You might even recycle the LoadLibrary/FreeLibrary reference counter, however that might hit performance.
Also, none of these schemes help much if you get circular DLL dependencies (Component DllA.X references DllB.Y, which references DllA.Z). I haven't yet fould a good solution to that that doesn#t requrie global knowledge.
For the case where the DLL is switched at run time, I'd avoid the smart pointer system for objects created by the DLL and use a system like this:
|-----------------------| |--------------------------|
| Abstraction Interface | | Implementation Interface |
|-----------------------| |--------------------------|
^ ^
| |
|-------------|1 *|-------------------|* *|----------------|
| Application |-------| Abstraction Layer |--------| Implementation |
|-------------| |-------------------| |----------------|
\------------- Main Program ------------------/ \-------- DLL --------/
The application holds a list of all the allocated abstraction layer objects. The abstraction layer objects are the only objects that are allowed to own pointers to objects created by the implementation layer. When swapping DLLs, first iterate all abstraction layer objects and tell them to release the implementation specific data. Then unload the DLL and load the new DLL. Then iterate the abstraction layer objects again and tell them to create new implementation specific data.
MSDN is explicit on this topic: "A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur. For details, see the Remarks section of FreeLibraryAndExitThread.
Ok I think the best choice is to use the COM approach of polling the dll to see if it can be unloaded. How can I go about doing this though so that I can continue polling the dll after everything else has closed down (ie the main thread has terminated)? Do I need to create a completly seperate process to do this, in which case how do I do it so this seperate process knows about all the loaded dlls, and in a way which has VERY little impact on proformance?
Mayby I could just create the polling system when all the DllPtr's are out of scope and terminate it as soon as it has free the dll? That way it only exists for as long as it takes for any remaing smart pointers to be destroyed.