The hazards of appropriate cleanup

by Michael S. Kaplan, published on 2008/06/23 03:46 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/06/23/8639629.aspx


There was a mail thread that happened recently on one of those "if you aren't a fulltime employee then why the hell are you here?" kind of aliases, one that I belong to because by following along the problems (and occasionally looking at the remotes) I became much better at debugging.

Plus sometimes I even have unique information about a problem (since my areas of expertise occasionally come up!). A few times I even ended up with International Fundamentals consulting work, helping people out with issues that I noticed. It isn't really ambulance chasing, but it is being somewhat near the ambulances in case the patients happen to need my help. :-)

Anyway, they were talking about one of those interesting kind of bugs that pop up from time to time where somebody was delay loading a library during process exit and of course this was leading to other interesting problems.

That horror story Raymond covered in Quick overview of how processes exit on Windows XP? That came up at one point, kind of a reminder about all the things that happened on thread tear-down that you just didn't want to bother with on process tear-down. Because they take too much time and may deadlock (plus in the case of this bug, actually did).

And then someone asked me if I had this problem with the MSLU (Microsoft Layer for Unicode on Win9x Systems). He knew that we did some unload work....

Actually, we don't do much here.

What we almost did, that is the interesting part....

We added a function to UNICOWS.LIB that you can find if you spelunk through the symbols (which some folks have) named:

___FreeAllLibrariesInMsluLoader

And a sister function exported from the UNICOWS.DLL called:

__FreeAllLibrariesInMsluDll

These functions take no parameters and need none, either -- the former calls FreeLibrary on everything it called LoadLibrary on in the code inside the .LIB that is compiled into the application, and the latter does the same with all of the libraries loaded by the DLL, and clears all the function pointers.

Technically, these actions are useful in the case of MSLU being completely unloaded, which is why they exist. There was even some discussion at the time about putting it in the DLL_PROCESS_DETACH code in MSLU's DllMain, which at the time just had TLS cleanup code and such.

But in the end, the decision was to leave the call out, since most people did not need function pointers private to MSLU to be so religiously unloaded -- given that once MSLU is unloaded no one could be calling them anyway.

In fact, the main benefit of them is for when the thing that loaded MSLU may have leaked out function pointers to MSLU functions -- which means someone else may try to call the DLL. If it still happens to be in memory but its TLS information is gone, trying to call into it can cause it to use random memory information as if it was valid handles and function pointers. And in such cases it is much better for the code to crash immediately (which it will when all the pointers have been changed to NULL).

A rare scenario, obviously. But one that is important every once in a great while.

And people have found these functions in the past; there are even components and applications that use them due to their wholesome, cleanupy sound.

So I figure they at least deserve a mention, now.... :-)

This blog brought to you by(U+1803, a.k.a. MONGOLIAN FULL STOP)


no comments

go to newer or older post, or back to index or month or day