Monday, August 25, 2008

DLLMain() Don'ts

{if not programmer, escape}

I never knew this, but it makes Oh, So Much Sense Now.
You can define a special function in a Windows DLL called DLLMain(). It's a piece of code that gets executed when your DLL is first loaded into the address space of your process. (It also gets called at other times, like thread attachment and shutdown). But that's not the bit I didn't know. I was recently debugging a problem where loading a DLL was causing a system crash. It looked as though the static variables in a dependent dll (loaded as a result) were not initialised, and thus any attempt to use them was causing massive, sudden and irrevocable system carnage. Now, the DLLMain of one of the dependant DLLs was calling a fairly innocuous trace function, however, the tracing platform was doing some funky dynamic loading of implementation DLLs to get around some tracing dependency issues. The problem with this is that when the CRT calls your dll's DLLMain() function, it takes out a lock (called the loader lock) on DLL loading (actually initialising loaded DLLs). This means that dynamically loading DLLs during a DLLMain is a Really Bad Thing. IMHO, this really should have completely deadlocked rather than trying to do what it did. Perhaps it would have deadlocked if any of the dependent DLLs defined their own DLLMain() functions. What it actually did was to load the DLL as asked, but not initialise any of the static data for it. Nasty.
More info.

No comments: