Finally, some more concrete guidance on the mystery’s of DllMain


I spent many years prior to coming to Microsoft doing “dangerous” things inside of DllMain. If you’re a diagnostic tool developer, it’s often the only reasonable place to take key actions that must occur as soon as possible.


Unfortunately, the MSDN doc has long warned against doing much of anything inside your DllMain code. Unfortunately, the list of “OK” things to do seemed unreasonably restrictive, and I could never find a comprehensive list of why things shouldn’t be done inside DllMain.


A big part of the issues concern the relatively undocumented “Loader Lock”, which is essentially a critical section that the OS enters and leaves on your behalf in a variety of places, not just DllMain. Without a good understanding of it, you might go nuts trying to figure out why some seemingly fine piece of code chokes.


I learned about many mysteries of DllMain the hard way. Now it’s finally here in blessed MSDN form:


http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx


Interestingly, one useful nugget of information that’s not in the article is that GetProcAddress temporarily requires the loader lock. (At least that’s my recollection from a few years ago. It may have changed since then. YMMV.)


If only this document had been around 13 years ago when I first needed it!


 


Comments (5)

  1. On the documentation page of my website, http://www.smidgeonsoft.com, one will find notes on the loader lock that I put together a while back.  These observations were based on WinXP SP1.  One interesting fact that I learned was that two APIs were added to NTDLL for WinXP called LdrLockLoaderLock and LdrUnlockLoaderLock.  My notes include a cross-reference to DLLs outside of NTDLL that were using these APIs as well as a comprehensive list of where inside NTDLL the loader lock was referenced.

  2. BTannenbaum says:

    WTF?  The first paragraph of "General Best Practices" makes no sense.

    The document claims (as we know from long experience) that the loader lock is acquired before calling DllMain, and that the loader lock can be acquired recursively, like any CritalSection.  Then goes on to state in "General Best Practices" "You cannot call any funciton in DllMain that directly or indirectly tries to acquire the loader lock.  Otherwise, you will introduce the possibility that your application deadlocks or crashes."

    I can’t see how a deadlock is possible in this case.  I would agree that DllMain should not acquire any OTHER lock, either directly or indirectly, since you risk a deadlock with another thread which has that lock and needs the loader lock, but the calling functions that acquire the loader lock should be totally safe at this time since I’ve already got the loader lock.

  3. JeffCurless says:

    I think that this is a much better overview than that document.

    http://blogs.msdn.com/mgrier/default.aspx