.net - 程序终止时出现 LoaderLock 错误

标签 .net c++ unmanaged loaderlock

我最近将 .NET NLog 日志记录组件集成到我们的一个应用程序中,该应用程序完全使用非托管代码(在 Visual Studio 6 中编译的 C++ 和 VB6 组件)开发。我们有一堆 C++ 应用程序通过 COM 接口(interface)与 NLog 对话。

目前一切正常,但我确实注意到在程序终止期间弹出以下消息(如果在 VS6 中调试 C++ 组件,则在输出窗口中;如果通过 VS 2005 调试 NLog,则作为 IDE 中的提示):

LoaderLock was detected Message: Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.

DllMain如下:

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

我的猜测是 _Module.Term(); 现在包括释放一些 .NET 引用(我在我的一个 C++ 类中保留对 NLog 对象的引用以避免必须实例化并每次释放)导致弹出此警告。

我的问题:忽略这个安全吗?如果不是,什么是好的解决方法? (我能想到的最好的办法是实例化对该 NLog 对象的引用,并在每次我想写入日志文件时释放它……这不是最优雅的解决方案)

最佳答案

忽略此消息绝对是不安全的。如果您看到此消息,几乎可以肯定您已经创建了一个真正的加载程序锁定策略违规。这是一个非常严重的错误,可能会导致程序出现不可预知的行为(包括死锁)。

避免这种情况的最佳方法是不要在 DLL main 中直接或间接访问任何其他 .Net 对象/函数。对于您的情况,最好使用不同的缓存策略。也许创建一个引用计数对象来保存 .Net 引用。这样,对象将在调用 DllMain 进行卸载之前被释放(在销毁所有对象之前无法卸载 dll)。

关于.net - 程序终止时出现 LoaderLock 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/490430/

相关文章:

.NET集合和大对象堆(LOH)

c# - 在 C# 中显示后立即关闭窗体

.net - SQL Server 数据库插入/更新 TCP 通知

c++ - 在 Visual Studio 2012 中使用 GUI 和数据库的 Windows 应用程序

c# - 在 asp.net web 应用程序中使用后无法删除托管 dll

c# - 在 C# 中为 Print Spooler API 设置标志?

.net - IE6中的垂直滚动条

c++ - 静态正则表达式对象还是重要的?

c++ - 如何在 C++ 中实现强大的数据持久层?

c++ - Easyhook:非托管 Hook ,如何调用原始函数/更改返回状态?