Out-of-order Dll Teardown

Danilo Almeida dalmeida at MIT.EDU
Wed Jan 29 22:45:46 EST 2003


Your logic is correct.  Option [1] is appropriate if and only if you know
the process is being torn down.

>From MSDN docs for DllMain:


If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain has been
called by using FreeLibrary and non-NULL if DllMain has been called during
process termination.

Therefore, if reason is DLL_PROCESS_DETACH and reserved is non-NULL, B.dll
can punt freeing up the context, etc.  If you have any persistent state that
needs to be cleaned up (i.e., you need to destroy tickets*), then you still
need to have some kind of cleanup routine in B.dll that gets called before
the app exists.

- Danilo

-----Original Message-----
From: krbdev-bounces at MIT.EDU [mailto:krbdev-bounces at MIT.EDU] On Behalf Of
Ben Creech
Sent: Wednesday, January 29, 2003 7:04 PM
To: krbdev at MIT.EDU

This question isn't exactly Kerberos-specific, but it is still pertinent
to this list.  In summary, I'm getting odd behavior from Windows on
teardown of KfW's krb5_32.dll.

As noted in athena\auth\krbcc\src\dll\cacheapi.cxx, Windows doesn't
follow the Dll dependency tree when tearing down Dlls with calls to
DllMain with DLL_PROCESS_DETACH.  For example, if A.exe loads B.dll
which in turn loads C.dll, Windows apparently sometimes tears down C.dll
before B.dll (A->C->B instead of A->B->C).

I say "apparently" because I have observed this in my own program. 
A.exe loads B.dll which delay-loads krb5_32.dll.  B.dll calls
krb5_init_context.  Things Happen.  A.exe exits.  Windows tears down
krb5_32.dll, which shuts down the ccache connection and frees its heap
(via the run-time library).  At this point, B.dll's DllMain is finally
called.  As part of the cleanup routine, B.dll calls krb5_free_context. 
Whoops, that's no longer a valid pointer!  Program crashes.

Of course, I can simply comment out my krb5_free_context since the
process is exiting anyway [1].  Alternately, I can make A.exe call a
cleanup function before it exits [2].

Incidentally, I didn't get this behavior until I started using debug
dlls from 2.2-beta-2; the downloadable 2.1 release build didn't do it. 
After poking through the code, I'm fairly satisfied that 2.2 added
nothing that would cause my problem, so it's probably the fact that I'm
using debug binaries now.

Can anyone tell me if my logic is correct?  I'm worried that I'm either
doing something wrong on my side, or there is a subtle bug in 2.2 beta 2
(is anyone testing it with delay-loading)?

Ben Creech

krbdev mailing list             krbdev at mit.edu

More information about the krbdev mailing list