I have a windows DLL with functions InitInstance and ExitInstance.
The DLL creates some threads, worker threads with _beginthreadex and threads with Message Queue,
derived from CWinThread (MFC).
The DLL should useable by any application.
I wrote a small host application for this DLL to test and it worked fine, except
when i close this host application without calling FreeLibrary before. In this case, ExitInstance
is called as well, but all threads are disappeard, which is quite unusual and leads to a deadlock
as some routines waiting for a thread finished which does not exist any longer - as it was
finished or killed.
I need to go this way (skip to call FreeLibrary) in order to simulate what could hapen when
other applications use this DLL.
ExitInstance is called, but all threads which
normally still running are disappeared - most probably because DLL is handled somehow differently
when unloaded from host process if you do not call FreeLibrary before.
They disappear silently, for instance, if a thread just implements a loop with a WaitForSingleObject within loop, this thread is not finish normally.
thread()
{
while(running == true)
{
WaitForSingleObject(...);
}
threadfinished=true; /// 1
}
If calling FreeLibrary before closing application, code section 1 is called.
When closing application without calling FreeLibrary before, code section 1 is never called
but loop also not running any longer as thread was removed.
How should I handle this situation ? Thank you
The documentation for CWinThread::ExitInstance is very clear: "Do not call this member function from anywhere but within the Run member function." (i.e. CWinThread::Run, the thread itself).
Obviously, that means Windows is NOT going to call ExitInstance for you. Nor is the host application, since that has no idea about your threads.
What is called is DllMain, but only once and with argument DLL_PROCESS_DETACH. You won't get DLL_THREAD_DETACH because that happens after your threads exit cleanly (i.e. ExitInstance or returning from CWinThread::Run).
By the way, consider what code your threads could be running after your DLL has been unloaded. It can't be your functions or MFC, since those functions no longer exists. The thread would crash with an Access Violation because its instruction pointer now points to unallocated memory.
Related
I'm used to work with good old WinAPI call CreateThread(), and check thread's status using the waiting function, e.g WaitForSingleObject(), Once thread thread is signaled with WAIT_OBJECT_0, i close it using CloseHandle().
Recently I've decided to move to beginthread and somehow avoid the risks of uninitialized crt and accidental memory leaks that may happen.
Doing that got me confused.
What's the exact purpose of endthread()? why when i call CloseHandle() in the main function, after thread's execution, CloseHandle() crashes with invalid handle?
Should i ever close the handle returned by beginthread?
endthread, As i understood is invoked automatically by the thread once my function goes out of scope, so should i call it anyway just before i get out of scope?
According to msdn, endthread already calls CloseHandle() 1.From where does the thread obtain a reference / instance to its handle. 2. If i do insist on using endthread(), should it be the last command in the thread?
thanks
EDIT: MSDN paper describing the leaks, here.
As stated in the comments by David Hefferman you can simply change your code back to using CreateThread. The Visual C++ runtime (CRT) will automatically initialize the CRT's per thread data the first time you use a function that uses the per thread data.
The CRT will also automatically free the per thread data when a thread ends, so using CreateThread won't cause memory leaks. There is one exception, if all of the following conditions are true then per thread data isn't automatically freed:
You're building an executable, not a DLL
You're linking against the static version of the CRT library (LIBCMT.LIB) instead of the DLL version (MSVCRT.LIB)
The executable you built is run under Windows XP (or an earlier version of Windows).
Note that even if all this true in your case, the memory leak isn't going to be significant unless you're creating a long lived application that creates and destroys hundreds of thousands of threads over its life time.
If you still want to use the CRTs thread creation functions (_beginthread/_beginthreadex) you should follow these guidelines:
Never use the handle returned by _beginthread. With _beginthread the thread handle is automatically closed when the thread exits, which can potentially happen before _beginthread even returns. You can't use it with WaitForSingleObject safely because the thread might have already exited before you call this function. If you want to use the thread handle for anything use _beginthreadex instead.
You should never close the handle returned by _beginthread. The CRT will do it automatically, and as described in the previous point, may do so before you have chance to.
You should always close the handle returned by _beginthreadex when you no longer need it. The CRT won't do this automatically for you, so it's your own responsibility.
Don't call _endthread or _endthreadex unless you want to quickly and abnormally terminate the thread. While the CRT will free its own per thread data, none of the C++ destructors for any of the thread's objects will be called. It behaves similarly to how _exit ends the process without calling destructors.
The normal means of ending a thread should be by returning from the function passed as an argument to _beginthread or _beginthreadex. This will result in C++ destructors being called as a normal part of the function return.
I have one instance (global/static object) ClassA inside of my delay-loaded DLL. This object inside has an "Observer" thread which is required to perform graceful shutdown. When I call FreeLibrary I noticed that during deletion of this static object my thread requested to shutdown but hangs on _endthreadex() and causes deadlock. It doesn't matter if I call _endthreadex explicitly or implicitly. It doesn't matter if object is global or static - same result.
This thread wrapped in ClassB (implemented by template with custom message loop). There is a request to shutdown thread (post message) and following WaitForSingleObject which never returns for given thread heandle.
Same "template thread class" used everywhere in the code and shutdown works great. The only issue when deleting static obj. I think there is some lock inside of _endthreadex() which is already locked upon dll unload and deleting of static objects.
Thread started with _beginthreadex.
ps. When I instantiated same static obj inside of App - app closes without any significant issues.
Any ideas why _endtreadex causes deadlock? How to avoid it?
This particular case is easy to explain. The _endthreadex call needs the loader lock so that it can call DllMain with DLL_THREAD_DETACH. The thread that called FreeLibrary, however, already holds the loader lock, because you're already in the middle of a call to DllMain with DLL_PROCESS_DETACH.
The other way this can break is that if the process exits without explicitly unloading the library, your observer thread will be terminated before the DLL_PROCESS_DETACH call, so when you try to signal it to exit, it won't respond because it isn't running any more.
The best approach is probably to create explicit InitializeLibrary() and UninitializeLibrary() functions for the user to call.
I have thread A that is creating another thread B, than thread A is waiting using WaitForSingleObject to wait until thread B dies.
The problem is that even though thread B returns from the thread's "thread_func", thread A does not get signaled!.
I know that because I added traces (OutputDebugString) to the end of the thread_func (thread B's main function) and I can see that thread B finishes its execution, but thread A never comes out of the WaitForSingleObject.
Now, I must also add that this code is in a COM object, and the scenario described above is happening when I'm calling regsvr32.exe (it get stuck!), so I believe that thread A is coming from the DLLMain.
Any ideas why thread A does not get signaled ?!?!
You could be hitting a problem with the loader lock. Windows, has an internal critical section that gets locked whenever a DLL is loaded/unloaded or when thread is started/stopped (DllMain is always called inside that lock). If your waiting thread A has that critical section locked (i.e. you are waiting somewhere from DllMain), while another thread B tries to shutdown and attempts to acquire that loader critical section, you have your deadlock.
To see where the deadlock happens, just run your app from the VS IDE debugger and after it gets stuck, break execution. Then look at all running threads, and note the stack of each one. You should be able to follow each stack and see what each thread is waiting on.
I think #DXM is right. The documentation on exactly what you can or can't do inside of DllMain is sparse and hard to find, but the bottom line is that you should generally keep it to a bare minimum -- initialize internal variables and such, but that's about it.
The other point I'd make is that you generally should not "call" regsvr32.exe -- ever.
RegSvr32 is basically just a wrapper that loads a DLL into its address space with LoadLibrary, Calls GetProcAddress to get the address of a function named DllRegisterServer, then calls that function. It's much cleaner (and ultimately, easier) to do the job on your own, something like this:
HMODULE mod = LoadLibrary(your_COM_file);
register_DLL = GetProcAddress(mod, "DllRegisterServer");
if ( register_DLL == NULL) {
// must not really be a COM object...
}
if ( S_OK != register_DLL()) {
// registration failed.
}
i have couple of query's with respect to DLL,
1)If i load the DLL in run time, i guess DLL will be in separate thread right?
2)If i call a function present in DLL, and that function takes much time to return the value then how can i make my application thread to wait till the DLL's function return value.
How can i solve the second problem
Your assumption is incorrect.
If you load a DLL, and then call one of its functions, the call is made synchronously, just like any other function call.
There is absolutely no reason why the DLL should be loaded in another thread. You may do it, of course, but this is not the default.
1) No. The dll is just code. The code in the dll is called in the context of whatever threads you create. *
2) As a result, your application will wait for the dll's function to complete.
A Dll can create worker threads as a result of your application calling the dll. However, you cannot call directly into a thread. Any call your code makes will always happen synchronously on the current thread.
Are you using qt threads? Otherwise I cannot understand why you would use the "qt" tag.
As for your problems it seems to me that you have to create another thread which will call the function contained in the DLL.
When this thread exits than you can assume you have the function's result.
You can in switch implement DLL_THREAD_ATTACH too.
You must call this function from thread you want to slow down, or get Thread Suspend before function call, and Thread Resume after.
I have some code which I did not originally create that uses _beginthreadex and _endthreadex. For some reason, when it calls _endthreadex(0), the call just hangs and never returns. Any ideas as to what would normally cause this call to hang?
My answer is too far late, but still someone will use it.
In my case _endthreadex hanged when I unload dll and deleted some global objects. One of global objects had another thread inside and that thread also performed thread exit. This caused deadlock since DLLMain already locked crt memory map. Read DLLMain help and find that you are not allowed do any other action on another threads or processes during DLLMain call.
_endthreadex ends the thread, so it can't return. That's the whole point of calling it.
EDIT: It's a bit unusual to call _endthreadex, normally you just let the thread start procedure return and the runtime calls _endthreadex for you. You may need to explain a bit more, what you are trying to do before we can help.
Are you mistakenly calling _endthreadex() to attempt to end a thread from the main thread?
The function _endthreadex() is meant to be called inside the thread that you want to terminate to report a return value, and for the proper "recovery of resources allocated for the thread." You shouldn't need to call it in a destructor from the main thread. You could, in a destructor, signal to the thread via an event (see SetEvent, called from the main thread) that the thread should exit as soon as possible, and then the thread that is exiting as its last statement would call _endthreadex().
Calling _endthreadex() in your main thread would cause the process to hang, because you've terminated your main thread, but you would still have the original thread you wanted to terminate still running.
Ok....well, endthreadex gets called in the deconstructor of my class via "delete classinstance"...and that deconstructor call never returns...so the whole thing hangs