问题标签 [loaderlock]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
82979 浏览

c# - 加载程序锁定错误

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

我得到一个错误,说

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

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

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

0 投票
2 回答
941 浏览

.net - 程序终止时的 LoaderLock 错误

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

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

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

DllMain 如下:

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

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

0 投票
1 回答
5418 浏览

c# - LoaderLock was detected, and turning off the warning does not work

I am trying to write an application that takes in sound from the default audio recording device on a computer. When running any code that accesses DirectX from my managed code i get this error:

DLL 'C:\Windows\assembly\GAC\Microsoft.DirectX.DirectSound\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectSound.dll' is 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.

and

and

all cause the LoaderLock MDA to pop up and tell me there is a problem. I have scoured the internet (stackoverflow included) for solutions to this problem, but most people just say to turn off the warning, which does not work. When I turn off the warning, a generic ApplicationException is thrown, which is even less useful. I have seen the answers to this question as well, which didn't help because he said to remove the code that is causing the error. Others have said "fix your code."

My questions are:

how can I call any (preferably managed) DirectX code from C# without getting this error?

edit: this is the stack trace I get:

0 投票
2 回答
2442 浏览

c++ - 托管 c++ dll 的加载程序锁定错误,静态链接到本机 c++ 库

我有一个托管 c++ dll,其中包含几个托管类,这些托管类反过来调用我静态链接到 dll 的库中的本机 c++ 代码。但是,如果我尝试在 dll 上运行 RegAsm.exe,该工具会正确报告“没有我们注册的类型”,但随后会挂起。我很确定这是一个加载程序锁定问题,当 RegAsm 尝试加载它时,我的 dll 挂起。我正在使用 Visual Studio 2008,速成版。

令我困惑的是,将本机代码放入 dll 时一切正常,但从库中静态链接时却不行。我知道这篇文章与这个问题类似,但我的 dll 中没有 DllMain,我没有从 DllMain 运行 MSIL 代码的风险。此外,遵循在单个文件上设置 /clr 的建议也无济于事。

使用 /NOENTRY 编译 dll 可修复锁定问题,但会导致应用程序因Type initializer for <Module> threw exception异常而中断,并且显然仅在 .NET 2003 中推荐使用。

我怀疑静态成员的初始化可能是罪魁祸首,但为什么在我的静态库中将其编译为 MSIL 超出了我的范围。

澄清一下:虽然我不需要在 dll 上运行 RegAsm.exe,但我使用它来检查加载程序锁定问题。实际上,我正在使用 ac# 程序集中的 dll,它确实实现了几个 COM 可见的类 - 所以我需要在那个上进行 COM 注册。最后,C# IDE 在注册 COM 互操作期间崩溃,报告“R6033 c++ 运行时错误:尝试在本机代码初始化期间使用此程序集中的 MSIL 代码。这表明您的应用程序中存在错误。这很可能是从本机构造函数或 DllMain 调用 MSIL 编译 (/clr) 函数的结果。

解决了这个问题,但很少有事情不清楚,我很好奇:

我注意到当事情停止工作时,两个静态变量被添加到静态链接库中的头文件中,看起来像这样:

将初始化移动到 .cpp 文件(并更改staticextern)修复了加载程序锁定。谁能指出为什么初始化程序会被编译为 MSIL?

在修复之前,如果我只 #included 托管 dll 中的头文件,则一切正常。但是,如果我包含标题并且还链接到库,那么事情就不起作用了。由于 lib 也在内部使用了标头,所以我最终得到了静态变量的两个实例吗?无论如何,为什么要抱怨运行 MSIL 代码?

尽管现在一切正常,但欢迎任何见解。

0 投票
1 回答
1415 浏览

winapi - 一个 GetModuleHandle 实现

我需要这样做,因为我在其中,DllMain()因此持有加载程序锁。我读过GetModuleHandle() 它还使用了加载器锁 [第 6 页],这会导致死锁。

GetModuleHandle() 如何实现?一些代码将是一个加号。

更新:因为我SetWindowsHookEx只在 WinXP 上使用。只是在评论中接受建议,走简单的路,并在第一次调用回调时使用 GetModuleHandle() 。

0 投票
2 回答
925 浏览

winapi - getmodulefilename 可能会阻塞什么?

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

谢谢。

0 投票
1 回答
616 浏览

wpf - VB.NET 2008 的加载程序锁定错误(仅限 Windows XP?)

当我在 Windows XP 上运行我的应用程序(WPF、VB.net 2008)时,我得到了奇怪的 Windows 错误。当我在出现错误和调试的机器上安装 VS2008 时。我遇到了加载程序锁定异常,所以我进入调试并删除了它。但是,当它安装在机器上时,我仍然会收到错误消息。

有没有办法在安装应用程序时删除加载程序锁定异常。我知道它可能不是最好的解决方案,但似乎只有当我使用 ReportViewer 启动 WindowsElementHost 时才会发生这种情况,这会导致问题,所以我真的不知道还能用它做什么。

所有版本的 XP 都有这个问题,就像 2003 一样。

在 Windows 7 和 Vista 中,我在调试和安装产品时从未遇到过该错误。同样的事情也适用于 2008 和 2008R2。

0 投票
1 回答
255 浏览

visual-c++ - 在 DLL_PROCESS_ATTACH 上加载文件 - 对于 loaderlock 是否安全?

我想创建一个加载ini文件DLL_PROCESS_ATTACH的dll。它与加载 dll 的可执行文件位于同一目录中。对于装载机锁,这可以安全地完成吗?

关于托比亚斯

0 投票
0 回答
661 浏览

c++ - 动态链接库最佳实践 - 如何避免死锁?

背景

我已阅读Dynamic-Link Library Best Practices并了解在DllMain中我能做什么和不能做什么。

现在,假设我有一个包含许多项目的 Visual Studio 2013 解决方案。每个项目生成不同的二进制文件/lib 文件。

假设我有一些实用程序项目,生成一个所有项目都使用的 lib 文件。

现在,这个实用程序项目可能会定义一些调用的通用函数,例如,基于上面链接的LoadLibrary 函数是这样的:永远不要从 DllMain 中执行以下任务

问题

  1. 我如何实现一个通用函数,“知道”它不能使用某些 API,因为它是在DllMain函数范围内被调用的?

  2. 是否可以访问 Windows 加载程序锁定,并在锁定时禁用某些调用或更改函数的算法?

例子

项目实用程序

项目A

项目 B

虽然对函数的调用在GetUserName()中非常好Project B,但在Project A

我想以避免这种情况的方式使 mu 解决方案变得聪明。

理论方法

当然,这if( IsLoaderLocked() )不是真正的代码。只是我想在调用“危险”API 之前评估的条件示例。

0 投票
0 回答
827 浏览

.net - C++/CLI 程序集中的异常 0xC0020001

The string binding is invalid. 当我尝试关闭一个相当复杂的应用程序时会发生这种情况,该应用程序由使用 C++/CLI DLL 的 C# EXE 组成,而不是依次引用多个 C++ 本机静态库和 DLL。(我使用的是 VS2013 和 Boost 1.55。)

出现问题的原因是_atexit(在 DLL 终止时)试图调用_t2m@???__Fep@?1???$get_static_exception_object@Ubad_exception_@exception_detail@boost@@@exception_detail@boost@@YA?AVexception_ptr@1@XZ@YAXXZ@?A0x8b93c95f@@YAXXZ,这是一个本地到托管的 thunk,并且 CLR 可能已经被关闭。

我的主要问题是为什么在本机终止处理程序中注册托管 thunk,因为根据定义它不能工作。一个相关的问题是为什么要为这种类型生成托管 thunk,因为据我所知#include,任何可以引用这种类型的东西要么在非/clr编译文件中,要么#pragma unmanaged/clr-编译文件,因此根本不应该有任何托管版本。(帮助#pragma managed说,定义模板是否被管理是定义点,而不是实例化点。)

也许我对此有误,但我一直认为,当#include在文件中为本地类型(在非/clr文件中实现)生成头/clr文件时,应该将其包装在一个unmanaged块中以防止 ODR 问题。

一个问题(我记得在这里读过但现在找不到链接)表明解决方案是删除所有编译指示,让编译器弄清楚。但是,这样做会导致Managed Debugging Assistant 'LoaderLock' has detected a problem启动。(调用堆栈只指向导致加载 C++/CLI DLL 的 C# 代码,这并不完全有帮助。)

这个问题表明存在关于模板实例化的编译器错误。鉴于这get_static_exception_object是一个模板,这似乎是合理的,但我不确定如何解决它。

虽然另一个类似注册错误的函数是_t2m@???__FstrMgr@?1??GetInstance@CAtlStringMgr@ATL@@SAPAUIAtlStringMgr@2@XZ@YAXXZ@@YAXXZ,它不是模板,所以这可能是一个红鲱鱼。

(我尝试在一个较小的示例中重现该问题,但还不能这样做。显然有一些我不知道的触发因素。)