Sign in to follow this  
Randy Gaul

Creating Threads in Reloadable DLL

Recommended Posts

If I create a thread from a DLL which links against it's own CRT, and then reload that DLL, does it mess with the thread in any way? I'm wondering if the main application should expose a wrapper to create threads, just to avoid any weirdness when the DLL is reloaded during runtime.

Reading here it seems like there's some weirdness involved in DLLMain: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx?f=255&MSPPError=-2147217396. However, I'm not using DLLMain at all. But just wanted to check here in case anyone had any knowledge to share.

Share this post


Link to post
Share on other sites

Unloading a DLL while any thread has a function in that DLL in its callstack = bad juju. The stack will unwind to a bogus address and you will (if you're very lucky) crash. This includes the original thread proc.

IIRC there is the option of using ExitThread to try to avoid this but I don't remember if it's advisable. Check MSDN.

The most robust thing to do is only fork threads from the main EXE *or* DLLs which you don't plan to reload.

 

https://msdn.microsoft.com/en-us/library/windows/desktop/ms683153 if you're feeling bold :-)

Share this post


Link to post
Share on other sites

Dang. OK in that case I'll just expose a wrapper callback from the main executable to my reloadable thread. I do want the reloadable thread to be able to spawn threads at-will, but have lifetimes in regards to the main executable.

Share this post


Link to post
Share on other sites

The callstack is already mentioned, but ANY pointer to that memory would be a problem.  C++ object virtual table pointers.  First class functions/lambdas/etc in a variety of languages.  There's also the possibility that something points to the DLL's static data, not just code.

It would be theoretically possible when loading the new DLL to rewrite all of the existing 'lingering' pointers to point at the appropriate place in the new DLL, but that would require tracking all of those pointers somehow, as well as having some way of identifying the symbol and offset they're pointing to (which may always not be available).  You also have to worry about the possibility that the new DLL removed a function/static variable, or rewrote some data types.

This is probably the reason why .Net's AppDomain and Assembly unloading is also so cumbersome to use for this kind of thing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this