【问题标题】:Assertion in appcore.cpp while loading regular DLL dynamically linked to MFC加载动态链接到 MFC 的常规 DLL 时 appcore.cpp 中的断言
【发布时间】:2017-02-12 20:08:04
【问题描述】:

我继承了一个应用程序,该应用程序包含一个动态链接到 MFC 的常规 DLL,该应用程序是从一个 Windows 服务可执行文件加载的,该可执行文件也动态链接到 MFC。该代码正在使用 Microsoft Visual Studio 2008 Professional(旧的,我知道...)进行编译。这个应用程序已经“工作”了好几年,但我发现由于 appcore.cpp 中的以下断言,我无法将它作为调试版本运行:

调试断言失败! 程序:C:\Projects\CMM\Debug\CMM.exe 文件:f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\appcore.cpp 线路:380

有关您的程序如何导致断言的更多信息 失败,请参阅有关断言的 Visual C++ 文档。

(按重试调试应用程序)

对应CWinApp构造函数中的如下代码:

ASSERT(AfxGetThread() == NULL);
pThreadState->m_pCurrentWinThread = this;
ASSERT(AfxGetThread() == this);

当通过 LoadLibrary 加载 DLL 时会发生这种情况,这让我怀疑应用程序多年来的工作更多是靠运气而不是判断(由于 ASSERT 未包含在发布版本中)。

我(诚然有限)对 MFC 的理解是,虽然通常应该只有一个 CWinApp 实例,但在常规 DLL 中可以有一个额外的实例,它动态链接到 MFC,就像在这种情况下一样。该代码在服务可执行文件中有一个实例,在 DLL 中有一个实例。 CWinApp 构造函数被调用 3 次 (?),一次用于 MFC 框架内的某个内部实例,一次用于服务可执行文件中的实例,一次用于 DLL 中的实例。前两个工作正常,第三个爆炸了。

所有导出的函数都以AFX_MANAGE_STATE 开头(尽管执行永远不会那么远)并且我相信预处理器标志是正确的 w.r.t。 Microsoft 的文档(_AFXDLL 用于 EXE,_AFXDLL_USRDLL_WINDLL 用于 DLL)。

我尝试使用AfxLoadLibrary 代替LoadLibrary 无效。但是,如果我包括

AFX_MANAGE_STATE( AfxGetStaticModuleState() )

在调用LoadLibrary/AfxLoadLibrary 的函数开始时,CWinApp 对象实际构造,但随后在 dllmodul.cpp 中执行失败。

谁能解释为什么会发生这种情况或我需要做些什么来解决它?

编辑

这是断言发生时的调用堆栈:

mfc90d.dll!CWinApp::CWinApp(const char * lpszAppName=0x00000000)  Line 380 + 0x1c bytes C++
cimdll.dll!CCimDllApp::CCimDllApp()  Line 146 + 0x19 bytes  C++
cimdll.dll!`dynamic initializer for 'theApp''()  Line 129 + 0xd bytes   C++
msvcr90d.dll!_initterm(void (void)* * pfbegin=0x1b887c88, void (void)* * pfend=0x1b887d6c)  Line 903    C
cimdll.dll!_CRT_INIT(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000)  Line 318 + 0xf bytes    C
cimdll.dll!__DllMainCRTStartup(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000)  Line 540 + 0x11 bytes C
cimdll.dll!_DllMainCRTStartup(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000)  Line 510 + 0x11 bytes  C
ntdll.dll!_LdrxCallInitRoutine@16()  + 0x16 bytes   
ntdll.dll!LdrpCallInitRoutine()  + 0x43 bytes   
ntdll.dll!LdrpInitializeNode()  + 0x101 bytes   
ntdll.dll!LdrpInitializeGraphRecurse()  + 0x71 bytes    
ntdll.dll!LdrpPrepareModuleForExecution()  + 0x8b bytes 
ntdll.dll!LdrpLoadDllInternal()  + 0x121 bytes  
ntdll.dll!LdrpLoadDll()  + 0x92 bytes   
ntdll.dll!_LdrLoadDll@16()  + 0xd9 bytes    
KernelBase.dll!_LoadLibraryExW@12()  + 0x138 bytes  
KernelBase.dll!_LoadLibraryExA@12()  + 0x26 bytes   
KernelBase.dll!_LoadLibraryA@4()  + 0x32 bytes  
mfc90d.dll!AfxCtxLoadLibraryA(const char * lpLibFileName=0x02a70ce0)  Line 487 + 0x74 bytes C++
mfc90d.dll!AfxLoadLibrary(const char * lpszModuleName=0x02a70ce0)  Line 193 + 0x9 bytes C++
CMM.exe!CMonDevDll::LoadDLL()  Line 207 + 0x1b bytes    C++
CMM.exe!CMonDevDll::LoadDllEntryPoints()  Line 268 + 0x8 bytes  C++
CMM.exe!CMonDevDll::Initialize(CMonDevRun * pMonDevRun=0x0019fe60)  Line 186 + 0x8 bytes    C++
CMM.exe!CCtcLinkMonDev::Initialize(CMonDevRun * pMonDevRun=0x0019fe60, CCtcRegistry & reg={...}, int nLinkId=1)  Line 546 + 0x18 bytes  C++
CMM.exe!CCtcLinkSwitchMgr::Initialize(CMonDevRun * pMonDevRun=0x0019fe60, CCtcRegistry & reg={...})  Line 188 + 0x14 bytes  C++
CMM.exe!CMonDevRun::Initialize(ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > szServiceName="CimService")  Line 257 + 0x16 bytes    C++
CMM.exe!CMonDevService::Run()  Line 202 + 0x2d bytes    C++
CommonFilesD.dll!CCtcServiceBase::ParseStandardArgs(int argc=-1, char * * argv=0x02a51b44)  Line 278 + 0xf bytes    C++
CMM.exe!main(int argc=4, char * * argv=0x02a51b38)  Line 126 + 0x16 bytes   C++
CMM.exe!__tmainCRTStartup()  Line 586 + 0x19 bytes  C
CMM.exe!mainCRTStartup()  Line 403  C
kernel32.dll!@BaseThreadInitThunk@12()  + 0x24 bytes    
ntdll.dll!__RtlUserThreadStart()  + 0x2f bytes  
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

【问题讨论】:

  • 你能告诉我应用程序是类成员还是外部成员。
  • @SantoshDhanawade, theApp 被声明为全局变量,它不是类成员,也没有外部引用。
  • 嗨@SantoshDhanawade,感谢您的链接。我实际上在发帖之前阅读了第一个,但它确实描述了我面临的问题。不幸的是,我没有从任何构造函数加载 DLL,也没有发现可执行文件和 DLL 之间链接参数的库版本中存在任何不匹配。第二个提到了AFX_MANAGE_STATE 宏,但是我导出的函数已经使用了它,并且无论如何执行都不会那么远。无论如何感谢您的帮助。

标签: visual-c++ dll mfc


【解决方案1】:

我终于找到了崩溃的原因。我的 DLL 使用的库静态链接到 Boost.Thread 并导致此问题,可能是由于运行时不匹配。将库更改为动态链接到 Boost 似乎已经解决了这个问题。

【讨论】:

  • 您提供的调用堆栈似乎表明,在运行全局对象初始化程序时发生了死锁。它看起来不像运行时(我假设您的意思是 C 运行时)不匹配。虽然动态链接解决了(如果你幸运的话,或者如果你不是的话)几个问题。
猜你喜欢
  • 1970-01-01
  • 2011-02-08
  • 2013-07-07
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多