【问题标题】:What might getmodulefilename block on?getmodulefilename 可能会阻塞什么?
【发布时间】:2012-06-22 22:21:53
【问题描述】:

我们有一个多线程应用程序。其中一个工作线程调用 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 中执行代码。

谢谢。

【问题讨论】:

    标签: winapi deadlock getmodulefilename loaderlock


    【解决方案1】:

    只是一些随机的想法:

    • 如果有 C++(不仅仅是 C)代码,则在系统持有负载锁时,可能还会执行 DLL 上的静态分配对象的构造函数。你不会在任何地方使用你的锁在这样的对象的构造函数/析构函数中吗?

    • 尽管你的锁可能存在错误,并且使用锁实际上可能只是“取消隐藏”一场比赛,例如更改某些线程中的某些操作时间。 DllMain() 和线程可能很棘手。见http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

    【讨论】:

    • 感谢您的想法,花了一些时间来考虑它们:为了使锁成为 dll 的一个因素,应用程序必须将该特定实例传递给应该很漂亮的 dll容易找到。没有看到那样的东西。锁似乎涉及它,因为当我能够重现问题时,移除锁似乎会导致死锁消失。永远不能排除改变时间。我还编辑了问题描述以包含一个使用 com 对象的线程,当我遇到这个问题时,它似乎总是在那里。
    • 那个问题已经存在,显然没有帮助。但是有很多方法可以导致DllMain() 死锁,我的链接也提供了一些方法。
    【解决方案2】:

    嗯,原来我描述的问题只是我们使用的库中另一个问题的症状。该库显然在两个不同的线程中使用了一些 wininet api,其中一个在 dllmain 和 loaderlock 中。这两个线程死锁,随后锁定了我们调用 GetModuleFileName 的线程。

    目前我知道的就这么多了,但是一旦我们从库的供应商那里得到更多详细信息,我会更新它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      • 2012-03-27
      • 2021-06-10
      • 2017-07-14
      相关资源
      最近更新 更多