关于C#:加载程序锁定错误

Loader lock error

我通过在C#中编写代码来构建C ++ dll。

我说错了

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.

我尝试搜索该错误的确切含义,但是我写的文章毫无意义,主要是说这只是一个警告,我应该在Visual Studio中将其关闭。
其他解决方案似乎是由于iTunes引起的,或者是在使用DirectX编程时发生了此问题。 我的问题与两个都不相关。

谁能解释,这实际上意味着什么?


您需要转到菜单Debug-> Exceptions,打开Managed Debugging Assistants,找到LoaderLock并取消选中

http://goo.gl/TGAHV


加载程序锁定的一般思想:
系统在DllMain中的一个锁(如-同步锁)中运行代码。因此,在DllMain中运行非平凡的代码就是"寻求死锁",如此处所述。

问题是,为什么要尝试在DllMain中运行代码?在DllMain的上下文中运行此代码是否至关重要,还是可以生成一个新线程并在其中运行代码,而不必等待代码在DllMain中完成执行?

我认为特定于托管代码的问题是,运行托管代码可能涉及加载CLR之类的东西,并且不知道在那里可能发生什么会导致死锁……我不会听从"禁用此警告"的建议"如果我是您,因为很有可能您会发现在某些情况下应用程序意外挂起。


.NET 4.0和更多最新框架的更新

这是.Net 2.0时代提出的一个古老问题,当时对混合模式DLL的支持存在严重的初始化问题,容易出现随机死锁。从.Net 4.0开始,混合模式DLL的初始化已更改。现在有两个单独的初始化阶段:

  • 在DLL的入口点调用的本机初始化,包括本机C ++运行时设置和DllMain方法的执行。
  • 托管初始化,由系统加载程序自动执行。
  • 由于步骤2是在装载机锁之外执行的,因此没有死锁。有关详细信息,请参见"混合装配的初始化"。

    为了确保可以从本机可执行文件加载混合模式程序集,您需要检查的唯一事情是将DllMain方法声明为本机代码。 #pragma unmanaged可以帮助您:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #pragma unmanaged

    BOOL APIENTRY DllMain(HMODULE hModule,
        DWORD  ul_reason_for_call,
        LPVOID lpReserved
        )
    {
        ... // your implementation here
    }

    同样重要的是,DllMain可能直接或间接调用的任何代码也必须不受管理。限制DllMain使用的功能类型是有意义的,因此您可以跟踪从DllMain可以访问的所有代码,并确保所有代码均已用#pragma unmanaged进行编译。

    如果编译器检测到未将DllMain声明为不受管理,则可以通过警告C4747来有所帮助:

    1
    2
    1>  Generating Code...
    1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint

    但是,如果DllMain间接调用其他托管函数,则编译器将不会生成任何警告,因此您需要确保该操作永远不会发生,否则您的应用程序可能会随机死锁。


    按ctr d + e,然后按"扩展托管调试助手"节点。然后取消选中LoaderLock。

    希望这会帮助你。


    请提醒那些VS2017用户,您需要禁用" exception helper"而不是" exception assistant"(在VS2017之前),以防止加载程序锁定错误,其设置路径为Debug-> Exception。刚遇到这个问题并浪费了2个小时来寻找解决方案...


    我正在构建一个C ++ CLR DLL(MSVS2015),它必须对非托管DLL进行调用并定义非托管代码。我使用#pragma托管和#pragma托管来控制代码给定区域的模式。

    就我而言,我只是将#pragma不受管理地放在DllMain()的前面,这解决了问题。
    似乎在想我想要DllMain()的托管版本。


    我最近在创建用本机代码编写的COM对象的实例时遇到此错误:

    1
    m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));

    这导致了所描述的错误。"检测到LoaderLock"-引发异常。

    我通过在额外的线程中创建对象实例来克服了此错误:

    1
    2
    3
    4
    5
    ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
    Thread myThread = new Thread(threadRef);

    myThread.Start();
    myThread.Join(); // for synchronization

    发生此问题的原因是Visual Studio中的调试器在一个或多个DLL文件中运行使用Microsoft Foundation Classes 8.0版的托管应用程序的方式。

    在以下位置有详尽的阅读:http://msdn.microsoft.com/zh-cn/library/aa290048(vs.71).aspx


    我的Visual Studio 2017实例中的设置路径是Debug-> Windows-> Exception Settings。 异常设置"窗口"显示在底部的选项卡组中(与单独的窗口相对),花了我一段时间才注意到。 搜索"加载程序"。


    推荐阅读

      linux剪切程序命令?

      linux剪切程序命令?,地址,工作,系统,命令,信息,标准,管理,目录,进程,文件,Lin

      linux命令行调用程序?

      linux命令行调用程序?,工具,环境,代码,初级,工程,系统,网上,服务,管理,发行,l

      linux命令错误代码?

      linux命令错误代码?,系统,密码,电脑,网络,手机,网址,软件,代码,设备,老板,Lin

      linux设备加载命令?

      linux设备加载命令?,系统,设备,信息,电脑,第一,命令,文件,分区,磁盘,详细信

      linux网卡加载命令行?

      linux网卡加载命令行?,系统,地址,代码,网络,设备,电脑,名称,网卡,技术指标,

      linux锁定帐户的命令?

      linux锁定帐户的命令?,系统,密码,情况,管理,工作,用户,帐户,账户,命令,权限,L

      程序执行linux命令?

      程序执行linux命令?,系统,工作,地址,环境,信息,管理,命令,文件,目录,程序,lin

      linux命令刷新加载?

      linux命令刷新加载?,系统,下来,工具,网上,命令,终端,环境变量,以下,文件,路

      linux退出程序命令?

      linux退出程序命令?,档案,管理,系统,命令,编辑,进程,模式,文件,程序,指令,lin

      linux和程序命令大全?

      linux和程序命令大全?,系统,工作,地址,管理,标准,信息,命令,时间,周期性,目

      linux程序命令不可用?

      linux程序命令不可用?,系统,网络,地址,命令,情况,名称,信息,服务,密码,程序,l

      linux锁定终端命令?

      linux锁定终端命令?,工作,密码,地址,系统,信息,命令,图片,状态,目录,用户,lin

      linux程序命令规则?

      linux程序命令规则?,地址,工作,系统,命令,情况,工具,信息,环境,设备,发行,Lin

      linux命令行锁定界面?

      linux命令行锁定界面?,系统,管理,地址,密码,工作,一致,数字,首页,快捷键,界

      linux中停止程序命令?

      linux中停止程序命令?,系统,管理,软件,档案,进程,命令,通用,名称,信息,名字,L

      linux命令行关闭程序?

      linux命令行关闭程序?,电脑,系统,进程,名称,程序,命令,结束,后台,步骤,快捷

      加载linux内核的命令?

      加载linux内核的命令?,系统,信息,地址,电脑,发行,设备,简介,平台,发展,基础,l

      linux下启动程序命令?

      linux下启动程序命令?,系统,服务,环境,情况,数字,设备,工程,软件,命令,网上,l

      linux命令和程序区别?

      linux命令和程序区别?,系统,标准,环境,情况,控制权,服务,软件,信息,命令,文

      linux命令忽略错误?

      linux命令忽略错误?,系统,地址,工作,信息,设备,命令,设计,灵活,观察,标准,lin