为啥调试时会收到“检测到 LoaderLock”警告?

Posted

技术标签:

【中文标题】为啥调试时会收到“检测到 LoaderLock”警告?【英文标题】:Why am I getting the "LoaderLock was detected" warning when debugging?为什么调试时会收到“检测到 LoaderLock”警告? 【发布时间】:2010-10-27 17:54:21 【问题描述】:

我正在为 AutoCAD 2009 开发一个插件。项目输出是一个类库。当我尝试调试和加载类库时,我收到此“检测到 LoaderLock 消息”。我写这些插件已经有一段时间了,这是我看到的第一条此类消息。

    我该从哪里着手解决这个问题? 什么是 LoaderLock,为什么现在困扰我?

检测到LoaderLock 消息:尝试在 OS Loader 锁内进行托管执行。不要尝试在 DllMain 或图像初始化函数中运行托管代码,因为这样做会导致应用程序挂起。

我去了Debug -> Exceptions -> "Managed Debugging Assistants",找到"LoaderLock",并取消选中"Thrown"复选框。

我可以再次调试,但我做了什么以及为什么必须这样做?这会给我带来其他问题吗?

【问题讨论】:

【参考方案1】:

加载程序锁是一个进程范围的锁,系统使用它来同步访问以将 DLL 加载到进程地址空间。加载 DLL、释放 DLL、查询 DLL 信息等的函数都获取加载器锁。通常对开发人员影响最大的是加载程序锁在 DllMain 运行时也被持有 - 这意味着您通常不知道的操作系统锁可以在运行代码时被持有。

可以将加载程序锁视为锁层次结构中非常低的级别。在 DllMain 期间在加载程序锁下运行的代码可能是死锁的原因。例如,CLR 有它自己的一组内部锁,它可以在加载 DLL 时持有这些锁。如果您从 DllMain 中调用托管代码,您可能会导致线程上的 CLR 在持有加载程序锁的同时获取这些锁之一。如果另一个线程上的 CLR 获得了该锁(导致 DllMain 中的原始线程阻塞),然后尝试加载将获得加载器锁的 DLL,您的进程将死锁。

听起来 CLR 正在尝试抢先检测在加载程序锁定下运行的托管代码。当您在调试器中看到此故障导致的堆栈时,请确定导致托管代码从 DllMain 中运行的原因并将其删除。

【讨论】:

【参考方案2】:

根据我使用 AutoCAD 的经验,可以安全地忽略 LoaderLock 警告。这并不表示您的代码有问题,而是由于 AutoCAD 加载和初始化应用程序的方式而引发了警告。

【讨论】:

我将@bojan-resnik 的回复标记为有用,因为它可能回答了 OP 的最后一个问题:这会给我带来其他问题吗?答案是“也许不是,问题‘可能’只是调试器问题,可以忽略。”我觉得这很有帮助,尽管 Michael 提供的信息当然对理解问题也很有帮助。【参考方案3】:

这是 Visual Studio 2005 中的一个错误。阅读本文了解更多详细信息:http://support.microsoft.com/kb/913996

【讨论】:

那个 KB 是一个很好的发现,但是在调试 Excel XLL 插件时,我在 VS2010SP1 中经常看到这个错误——这就是我进入这个线程的原因。

以上是关于为啥调试时会收到“检测到 LoaderLock”警告?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Dash 在通过 PyCharm 调试时会抛出 TypeError? [关闭]

为啥我的 iOS 应用程序在收到推送通知时会崩溃?

为啥 firebug 在调试时会改变网站的行为?

为啥 Visual Studio 在调试时会跳过我的方法?

为啥我在停止 MediaRecorder 时会收到 IllegalStateException?

为啥我在使用 foreach 时会收到 ***Error?