什么可能getmodulefilename阻止?

时间:2012-06-22 22:21:54

标签: winapi deadlock getmodulefilename loaderlock

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

我们可以并且已经从此锁中删除了GetModuleFilename调用,但仍然非常关注死锁是如何发生的。

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

似乎GetModuleFilename将获取加载器锁,这似乎是一个非常好的死锁候选者。

但是一般来说,加载器锁中的线程不会执行任何我们自己的代码,除非在dllmain中,按照上面的链接。

dll_thread_attach或detach可能会在加载器锁中以及另一个正在创建或销毁的workerthread中调用,但我没有看到任何方法会尝试获取我们正在使用的锁。

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

我怀疑的其他一个线程是使用com对象的线程。线程在开头调用coinitialize,因此应该在单线程单元中。这里与装载机锁相互作用的可能性是什么?

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

感谢。

2 个答案:

答案 0 :(得分:0)

只是几个随意的想法:

  • 如果存在C ++(不仅仅是C)代码,则在系统保持加载锁定时,也可以执行DLL上静态分配的对象的构造函数。你不是在任何地方的对象的构造函数/析构函数中使用你的锁吗?

  • 尽管有锁定,也许错误可能在那里,并且使用锁实际上可能只是通过例如“取消隐藏”比赛。改变某些线程中某些动作的时间。 DllMain()和线程可能很棘手。请参阅http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

答案 1 :(得分:0)

好吧,事实证明我所描述的问题仅仅是我们使用的库中不同问题的症状。该库显然在两个不同的线程中使用了一些wininet apis,其中一个在dllmain中,在loaderlock中。这两个线程死锁,随后锁定了我们的调用GetModuleFileName的线程。

这和我现在所知道的差不多,但是一旦我们从图书馆的供应商那里得到更多细节,我就会更新。