我的调试版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--&gt;C/C++--&gt;Code Generation--&gt;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

使用调试模式构建时,凭据提供程序 DLL 无法正确加载

在构建发布版本时引用调试 dll

如何使用 Delphi 代码调试 VC++ 中构建的 DLL 文件?

调试 ASP MVC 应用程序中使用的 C++ DLL

VS2012:调试器启动时ntdll.dll中的断点没有更多信息