1

我们有一个多线程应用程序。其中一个工作线程调用 GetModuleFilename 进行日志记录,我们已经看到了一个死锁,工作线程在调用 GetModuleFilename 之前持有一个锁,这将永远阻塞。

我们可以并且已经从这个锁中删除了 GetModuleFilename 调用,但仍然对死锁是如何发生的非常感兴趣。

在线阅读:http: //blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx

似乎 GetModuleFilename 将获得 loaderlock,这似乎是一个很好的死锁候选者。

但通常 loaderlock 中的线程不会执行我们自己的任何代码,除了上面链接的 dllmain 中。

可能会在 loaderlock 和另一个正在创建或销毁的工作线程上调用 dll_thread_attach 或 detach,但我看不出有任何方法会尝试获取我们正在使用的锁。

主线程也有可能尝试获取 GetModuleFilename 线程所持有的锁,而第三个线程正在持有 loaderlock 并在主线程上执行 sendmessage 或类似的阻塞?在这里,我也没有发现会发生这种情况的任何情况。

我怀疑的其他线程之一是使用 com 对象的线程。线程在开始时调用coinitialize,因此应该在单线程单元中。这里有任何与 loaderlock 交互的可能性吗?

无论如何,我们无法确定这种死锁发生的确切方式。因此,我希望获得一些想法,或者在其他情况下获得有关 loaderlock 的更多信息,以及是否有任何其他场景在可能阻塞的 loaderlock 中执行代码。

谢谢。

4

2 回答 2

0

只是一些随机的想法:

  • 如果有 C++(不仅仅是 C)代码,那么在系统持有负载锁的同时,也可能在 DLL 上执行静态分配对象的构造函数。您不在任何地方使用此类对象的构造函数/析构函数中的锁吗?

  • 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

于 2012-06-22T22:46:16.443 回答
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.

于 2012-07-19T21:50:38.247 回答