1

We have a multithreaded application. One of the worker threads calls GetModuleFilename for logging purposes and we've seen a deadlock where the worker threads held a lock before calling GetModuleFilename which blocks forever.

We can and have removed the GetModuleFilename call from inside this lock, but are still very much interested in exactly how the deadlock occurs.

Doing some reading online: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx

it seems that GetModuleFilename will acquire the loaderlock, that seemed like a pretty good candidate for a deadlock.

But generally threads inside the loaderlock would not be executing any of our own code, except in dllmain as per the link above.

a dll_thread_attach or detach might be called in the loaderlock and on another workerthread which is getting created or destroyed, but i don't see any way this would try to acquire the lock we're using.

It is also possible that the main thread tries to acquire the lock which the GetModuleFilename thread is holding, and a 3rd thread is holding the loaderlock and doing a sendmessage or something like that blocking on the main thread? Here also i've not found any circumstances under which this would happen.

one of the other threads which i'm suspicious of is one which uses a com object. the thread calls coinitialize at the beginning so that should be in single threaded apartment. any possibilities of interaction with loaderlock here?

Anyways we've not been able to identify the exact way in which this deadlock occurs. So i'm hoping for some ideas, or some more information about the loaderlock in terms of other cases is it being acquired, and if there are any other scenarios where code would be executed within the loaderlock which has the potential to block.

Thanks.

Mike Davis
  • 197
  • 11

2 Answers2

0

Just few random ideas:

  • If there is C++ (not just C) code, it is possible constructors of statically allocated objects on DLL are also performed while system holds the load lock. Don't you use your lock in such object's constructor/destructor anywhere?

  • Perhaps the bug might be there despite your lock, and using the lock may actually just "unhide" a race by e.g. changing some timing of actions in some thread. DllMain() and threads may be tricky. See http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

mity
  • 2,299
  • 17
  • 20
  • thanks for the ideas, took some time to think through them: in order for the lock to be a factor from a dll, the application would have to pass that specific instance to a dll which should be pretty easy to find. didn't see anything like that. the lock seems like it is involved because when i'm able to repro the problem, removing the locks seems to cause the deadlock to go away. can never rule out changing timing though. i also edited the problem description to include a thread which is using a com object which always seem to be there when i encounter this. – Mike Davis Jun 22 '12 at 23:03
  • Wrong link, use this one: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx – Hans Passant Jun 23 '12 at 01:01
  • That one is already in the question, and obviously did not help. But there are many ways how to cause deadlock with `DllMain()` and my link offers some too. – mity Jun 23 '12 at 06:22
0

Well, turns out the problem i described was merely the symptom of a different problem in a library we used. The library apparently used some wininet apis in two different threads, one of which was in dllmain and inside the loaderlock. These two threads deadlocked which subsequently locked up our thread which called GetModuleFileName.

That's about as much as i know for now, but i'll update this once we get some more details back from the vendor of the library.

Mike Davis
  • 197
  • 11