我有动态加载&卸载的DLL,需要COMCTL32.dll> = v6.0和MSVCR> = v9.0。为确保加载了正确的版本,我在Visual Studio项目设置中启用了清单文件生成,并将此条目添加到另一个清单文件中:
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
在测试程序中,我调用LoadLibrary()
后跟{DLL}的FreeLibrary()
,ProcessExplorer指示以下文件句柄泄露:
从反汇编调用堆栈跟踪中我了解到,在LoadLibrary()
上,自动创建了激活上下文,并打开了每个文件夹的句柄。但似乎未在FreeLibrary()
上删除激活上下文。
如果我删除清单文件并设置项目设置以禁用清单生成,则这些泄漏消失了。但是,这样我就无法确保使用正确的MSVCR和COMCTL,因为这个DLL是由我无法控制的进程加载的。
有没有办法在不删除清单文件的情况下删除此泄漏 ?
谢谢!
答案 0 :(得分:1)
ProcessExplorer HANDLE泄漏报告是激活上下文泄漏的症状。很可能这个泄漏是间接在你的代码中,因为你没有正确地调用MFC。
为了帮助您自己验证这是您的错误而不是MFC,您可以从AppWizard创建一个简单的MFC DLL而不需要任何代码,并确认当它是LoadLibrary / FreeLibrary多次时,没有累积泄漏。
缺少的OS调用是ReleaseActCtx,或者是导致释放失败的缺少DeactivateActCtx。在实践中,MFC正在为您调用这些函数,因此您将寻找某种类型的MFC调用。
最好的调试技术可能是跟踪或断开核心激活上下文创建/激活/停用/释放功能(http://msdn.microsoft.com/en-us/library/aa374166(VS.85)。 aspx)看看会发生什么。您可能会看到一堆调用,因此可能需要进行某种跟踪。理想情况下,您可以在每次调用时捕获callstack并查看它们。您的调试器可能可以帮助您执行此操作。最新版本的VS可以在遇到断点时运行宏。
顺便说一句,你是正确的,你需要清单文件,不应该删除它们。
马丁
答案 1 :(得分:1)
ProcessExplorer HANDLE泄漏报告是激活上下文泄漏的症状。很可能这种泄漏是间接在你的代码中,因为你没有正确地调用MFC。
与特定代码使用无关。该问题已得到Microsoft的确认:http://support.microsoft.com/kb/2624911
在调用UnregisterClass时,SHELL32.DLL中确实存在上下文激活泄漏,从而影响Windows Vista及更高版本。该问题的唯一解决方法是不重复加载和卸载SHELL32.DLL。微软正在考虑在较新版本的Windows中修复此问题。
答案 2 :(得分:0)
这些句柄可能不会泄露 - 只是缓存。如果您将测试程序更改为多次重复加载和卸载DLL,那么每次DLL卸载时是否会看到一对新的句柄泄漏?如果没有,那不是问题。
答案 3 :(得分:0)
您的DLL是否有机会使用MFC?
我有一个DLL的问题,它使用MFC并调用可能相关的AfxWinInit()
。这个DLL(错误地)反复调用AfxWinInit()
,结果发现它泄漏了每个调用的激活上下文。令人惊讶的是,这只发生在调用应用程序使用清单时。