我的调试版dll使用了redistributable和crash的发布版
Posted
技术标签:
【中文标题】我的调试版dll使用了redistributable和crash的发布版【英文标题】:My debug version dll uses a release version of redistributable and crash 【发布时间】:2016-01-05 15:10:54 【问题描述】:我有一个崩溃,仅在调试中,发生在 msvcr100.dll 中。我怀疑发布/调试存在差异。我不明白为什么这个 dll 作为这个可再发行版本的发布版本的依赖项(而其他 dll 以相同的方式编译不)
这是程序崩溃时的堆栈
ntdll.dll!_RtlpWaitOnCriticalSection@8() Unknown
ntdll.dll!_RtlEnterCriticalSection@4() Unknown
msvcr100.dll!_lock_file(_iobuf * pf) Line 236 C
bard.dll!std::basic_filebuf<char,std::char_traits<char> >::_Lock() Line 310 C++
bard.dll!std::basic_istream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base(std::basic_istream<char,std::char_traits<char> > & _Istr) Line 78 C++
bard.dll!std::basic_istream<char,std::char_traits<char> >::sentry::sentry(std::basic_istream<char,std::char_traits<char> > & _Istr, bool _Noskip) Line 99 C++
bard.dll!std::getline<char,std::char_traits<char>,std::allocator<char>
我用visual studio 2010编译,项目使用poco 1.4.1
以前的调试版本工作正常,对 msvcr100.dll 没有不必要的依赖。从那以后,构建过程发生了重大变化,我真的不知道该去哪里找。什么会导致这种问题?
根据依赖wallker,依赖是直接的,当我在调试中运行程序时,它指向这些函数:
GetProcAddress(0x75770000 [KERNEL32.DLL], "FlsAlloc") called from "MSVCR100.DLL" at address 0x71FABA3B and returned 0x75784EE3.
GetProcAddress(0x75770000 [KERNEL32.DLL], "FlsGetValue") called from "MSVCR100.DLL" at address 0x71FABA48 and returned 0x75781252.
GetProcAddress(0x75770000 [KERNEL32.DLL], "FlsSetValue") called from "MSVCR100.DLL" at address 0x71FABA55 and returned 0x757841C0.
GetProcAddress(0x75770000 [KERNEL32.DLL], "FlsFree") called from "MSVCR100.DLL" at address 0x71FABA62 and returned 0x7578354F.
当查看预处理器的相应输出时,我看到:
#line 6193 "C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\include\\winbase.h"
[...]
__declspec(dllimport)
DWORD
__stdcall
FlsAlloc(
PFLS_CALLBACK_FUNCTION lpCallback
);
__declspec(dllimport)
PVOID
__stdcall
FlsGetValue(
DWORD dwFlsIndex
);
__declspec(dllimport)
BOOL
__stdcall
FlsSetValue(
DWORD dwFlsIndex,
PVOID lpFlsData
);
__declspec(dllimport)
BOOL
__stdcall
FlsFree(
DWORD dwFlsIndex
);
【问题讨论】:
【参考方案1】:在 Visual Studio 中,转到 Property Pages-->C/C++-->Code Generation-->Runtime Library
并确保它是“多线程调试 DLL”而不是“多线程 DLL”。或者,如果您从命令行构建,它应该包含 /MDd 而不是 /MD 标志。
【讨论】:
是的,并确保仅在“调试”配置上执行此操作。根据我的经验,在更改选项时很容易忘记设置正确的配置(通常是 Base 而不是 Debug 或 Release),因此当您更改配置时,构建会突然失败。 此设置已在“多线程调试 DLL”上。还有其他方法可以通过静态导入或其他方式解决此问题吗?【参考方案2】:如果您不知道,您可以使用(优秀的)软件http://www.dependencywalker.com/ 找出二进制文件的依赖项。您将轻松查看调试的来源,并帮助您找出问题所在。
【讨论】:
我同意这是一个很好的工具,而且我已经使用过它。我的 dll 直接依赖于 msvcr100.dll。我用它更新问题。以上是关于我的调试版dll使用了redistributable和crash的发布版的主要内容,如果未能解决你的问题,请参考以下文章
C++ 应用程序(调试版)包含 VS 运行时库 msvcr90.dll 和 msvcr90d.dll