views:

163

answers:

5

In my application, I want to execute logic at the very last moment. The later, the better.

The reason for this is that I keep track of certain elements in my application (data structures, resources, ...), and at the end of the application, a routine looks at these elements and reports if they were not correctly closed, freed, deleted, ...

Until now, we did this using several tricks.

The first trick was to overrule the _heap_term function of the C run time (and some other functions as well in the C Run Time). The advantage was that this worked very well, but was limited to applications in which the CRT was statically linked in.

The second trick was to define a global variable like this:

#pragma init_seg(lib)
GlobalApplicationManager s_globalApplicationManager;

The pragma makes sure that this global variable is constructed before all other global variables, and - more important - that it is destructed after all other global variables. This way, we can put the checking logic in the destructor of this class.

Problem is that starting from Windows 7 the destructor is not called anymore in some situations. At this moment it is not clear what influences this, but we are sure that it is not called if we make a successful Oracle connection in our application.

What other tricks are there to execute code as late as possible in an application?

+2  A: 

I think that you should try to refactor your code: Any member variable should be destructed in the relevant class destructor.

for global variables, you may define a destruction function void func(), and call atexit(func) upon initialization.

Lior Kogan
In theory you are right: the class destructor should cleanup its own things. Problem is that part of the application is still in plain C. And we want the extra checks to notify developers if they forgot to cleanup certain things. Hence the checking logic at the end of the application. We also considered using atexit, but apparently, if the global variables are not cleaned up, the atexit function isn't being called either. Nevertheless, thanks for the suggestion.
Patrick
+7  A: 

Use /ENTRYPOINT. In your custom entry point, call the CRT entry point and then your final logic.

Ben Voigt
Good and original idea. +1.
Patrick
+1  A: 

There are number of sections defined by the CRT to which you can add your own calls with #pragma. By using the right name you can add code at various points of the initialisation and shutdown process. However the names are not easy to find.

Check out "crt0dat.c" in the CRT source installed with VS2010 for some of the names.

Richard
A: 

Why not just pass your window/application a custom message after the call to ShowWindow ?

C Johnson
+1  A: 

You could place your logic in a DllMain(DLL_PROCESS_DETACH) function in a helper DLL. This happens even after the EXE's entry point has returned (assuming that even returns - it might not due to TerminateThread) so it's more reliable and later than Ben Voigt's earlier suggestion.

Don't assume you can do too much, though. It's pretty much the very last place where you can execute logic, but you can't rely on other DLL's being present anymore. That's the entire point of DLL_PROCESS_DETACH. You can only count on Kernel32.DLL being left.

MSalters