为什么我在调试时收到“LoaderLock was detected”警告?

问题描述 投票:0回答:3

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

  1. 我从哪里开始尝试解决这个问题?
  2. 什么是 LoaderLock,为什么它现在困扰着我?

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

我去了

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

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

visual-studio-2005 class-library autocad
3个回答
17
投票

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

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

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


3
投票

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


1
投票

这是 Visual Studio 2005 中的一个错误。阅读这篇知识库文章了解更多详情。

© www.soinside.com 2019 - 2024. All rights reserved.