If processes are using the same DLL, each process gets its own private copy of that DLL's static (or "global") data.
So all you need to do is make the list be a global variable in a DLL, and link to that DLL from every application. That way, there is no need to pass anything additional around.
Your idea of trapping the destruction of the list is fraught with difficulties, due to the unpredictability of the order of destruction of objects in a multi-DLL process.
It would be a lot simpler to dump out the contents of the list at the end of your main
or WinMain
function.
If you're not using a smart pointer class in a consistent fashion, then do so. Also, it may be worth looking for cyclic reference counts - object A has a count on object B, and vice verse. This is a common cause of unreleased objects.
Update:
To force all static destructors to run and release objects, so you can then examine the entries in the list afterwards, you'll need to structure your application a certain way.
Suppose you have a very minimal EXE that launches the process, and loads a number of other DLLs that actually do all the work. These other DLLs are loaded with LoadLibrary, somehow (maybe by COM or a COM-like system). The LoadLibrary API works by either loading the DLL into the process, or else incrementing an internal reference counter on the DLL if it is already loaded. The FreeLibrary API decrements the counter until it reaches zero and then unloads the DLL (at which point the static destructors for that DLL will execute).
To this we now add our diagnostic DLL that holds a list of all outstanding reference counted objects. All the other DLLs use import-lib linkage to the diagnostic DLL, and the EXE uses LoadLibrary on it as well.
When main
is about to exit, the EXE goes through the list of DLL handles it previously loaded, and calls FreeLibrary on all of them. By keeping the diagnostic DLL loaded, it ensures it's still there at the end. That's the theory at least.
But in what order should the other DLLs be unloaded? If A.DLL has static pointers to objects defined in B.DLL, then you better unload A first. So you need to have some idea of how your various DLLs form a "layered" architecture, with higher layers depending on lower layers, thus giving you a safe order in which to unload them.
Also, once you've unloaded all the DLLs, any entries in the diagnostic list that refer to objects in the DLLs will now be pointing to valid data on the heap, but the vtable will be pointing at code that was defined by the DLLs that have now been unloaded, so you won't be able to call virtual functions on those objects. You should be able to examine their data though.