使用 Visual Studio 2013 为本机 DLL 正确生成 PDB 文件
Posted
技术标签:
【中文标题】使用 Visual Studio 2013 为本机 DLL 正确生成 PDB 文件【英文标题】:Generating PDB files correctly for a native DLL using Visual studio 2013 【发布时间】:2015-10-22 23:06:46 【问题描述】:昨天,我浏览了我们公司的项目并对其进行了更新,以修复我们配置它们的错误 (AFAIK)。
问题是在项目的属性页下,在Configuration Properties -> C/C++ -> Output Files
下,我们将Program Database File Name
设置为$(OutDir)$(TargetName).pdb
,与我们设置Configuration Properties -> Linker -> Debugging -> Generate Program Database File
的值相同。
我的理解是,第一个属性设置 pdb 文件的位置,其中包含在编译源代码期间创建的目标文件的符号,而第二个属性设置 pdb 文件的位置,其中包含生成的 DLL 的符号。对吗?
在这种假设下,为了防止它们发生冲突(我认为这是不需要的),我将第一个属性设置为 $(IntDir)$(TargetName).pdb
,但这破坏了生成的 pdb 文件(即调试器无法将其识别为 DLL 的 pdb 文件, 一位同事在上面运行了一个工具,但签名与二进制文件中包含的签名不匹配)。
奇怪的是,使用值$(IntDir)$(TargetName)2.pdb
(注意“2”后缀)解决了这个问题。我不明白为什么中间文件的名称很重要?
注意Configuration Properties -> C/C++ -> General -> Debug Information Format
设置为Program Database (/Zi)
【问题讨论】:
当前模块的符号包含在文件中:链接器->调试->生成程序数据库文件。 (msdn.microsoft.com/en-us/library/kwx19e36(v=vs.120).aspx) 这是你在调试时应该使用的。 微软在很久很久以前就犯了一个错误,他们永远无法修复。该 .pdb 文件不适用于调试器,也不包含调试信息。编译器使用它来跟踪构建,以加速后续构建。更改设置没有用。 哪个是linker下的,还是c++下的?您有相关文档的链接吗? 【参考方案1】:我会说你没看错:编译器生成目标文件。那时 DLL 还没有准备好,所以无论 PDB 文件包含什么,它都对调试没有帮助。
链接器处理完编译器的输出后,DLL 就存在了。那时,PDB 对调试很有意义。所以用于调试的相关文件在Linker -> Debugging -> Generate Program Database File
。
正如@HansPassant 在 cmets 中提到的,编译器设置不应该被触及。可惜已经发生了。在 Visual Studio 2013 或 2015 C++ 控制台应用程序中,C/C++ -> Output Files
的默认值为 $(IntDir)vc$(PlatformToolsetVersion).pdb
,因此最终名称类似于 Debug\vc120.pdb
或 Debug\vc140.pdb
。
恕我直言,更改编译器的输出文件应该无关紧要,只要名称不与链接器设置冲突。这正是发生在您身上的事情:编译器名称$(IntDir)$(TargetName).pdb
(相对路径)解析为与链接器名称$(OutDir)$(TargetName).pdb
(绝对路径)相同的文件。在这种情况下,链接器可能无法写入文件,因为它仍在被编译器使用或其他奇怪的事情。
【讨论】:
@Bwmat:我认为这不重要。但我实际上从未尝试过。您绝对不应该使用的唯一名称是$(IntDir)$(TargetName).pdb
,因为这会与链接器输出文件产生名称冲突。
@Bwmat:将其添加到答案中
但它不应该造成冲突,链接器一个进入 outdir 而另一个进入 intdir。
@Bwmat:在我的机器上从头开始的新 C++ 解决方案中,IntDir 是相对目录,OutDir 是绝对目录但指的是同一个目录。以上是关于使用 Visual Studio 2013 为本机 DLL 正确生成 PDB 文件的主要内容,如果未能解决你的问题,请参考以下文章
Windows 7 64 位 Visual Studio 2013 上的本机 cl.exe
Visual Studio 2013 C++ 本机代码中与互锁操作的线程同步挂起