在Visual Studio中将.pdb调试符号信息嵌入到.exe文件中。

13

我正在尝试使用一种分析工具来分析Windows中嵌入调试符号信息的可执行文件。在对几个开源项目尝试使用该工具时,我意识到大多数构建不会将符号信息保留在可执行文件中。我能够使用VS(2008)编译源代码,但构建通常会将调试信息保存在单独的.pdb文件中,而不是.exe文件中(不幸的是,我只想从.exe文件中读取调试信息而非.pdb文件 :-()。

有人知道如何使用Visual Studio将符号调试信息嵌入到单个.exe文件中吗?

5个回答

8

但是这将只受.NET Core支持吗? - Mathias Lykkegaard Lorenzen
我不这么认为,你为什么这么说?这似乎是一个普遍的编译器特性... - Shay Rojansky
因为只有CoreCLR似乎能够理解嵌入式PDB?还是我理解错了? - Mathias Lykkegaard Lorenzen
嗯,Roslyn(用于 .net core 和 framework)现在已经支持此功能,但是对于 .net framework,调试器尚未支持...我不知道... - Shay Rojansky
问候。我来自2023年的遥远未来。世界是一个黑暗的地方:我们中的一些人仍然需要针对.NET Framework 4.8进行开发。然而,我可以报告,使用嵌入式PDB(即在MSBuild中使用<DebugType>embedded)的.NET程序集和NuGet包在.NET 4.8及以上版本上完美运行,并且得到全面支持。这只是对那些困在4.7版本上的人来说是个问题,幸运的是,他们现在已经绝迹了,呼! - undefined

6

MSDN上说不可能。

无法创建包含调试信息的 .exe 或 .dll 文件。调试信息总是放置在 .pdb 文件中。


尽管这个答案在2014年发布时是正确的,但嵌入式PDB已经成为.NET世界的一部分自2016年起 - undefined

5
我还不知道如何做,但是MSDN上有一篇文章讲解了这个问题。
可移植可执行文件(即.exe.dll)的头部可以有一个标志(存档)
IMAGE_FILE_DEBUG_STRIPPED

Debugging information was removed and stored separately in stored separately in a .dbg file.

这意味着调试信息可以嵌入可执行文件中,并且可以选择将其移除并存储在单独的 .dbg 文件中。 来自 MSDN 文章 DBG Files(archive)

DBG 文件是便携式可执行文件 (PE) 格式文件,其中包含用于 Visual Studio 调试器(以及可能的其他格式,具体取决于 DBG 的创建方式)的 Codeview 格式的调试信息。当您没有某些代码的源代码时,例如库或 Windows API 时,DBG 文件允许进行调试。DBG 文件还允许您进行 OLE RPC 调试。

现在已经有了 PDB 文件来取代 DBG 文件,PDB 文件现在更常用于调试。

您可以使用 REBASE.EXE 实用程序从 PE 格式可执行文件中剥离调试信息并将其存储在 DBG 文件中。PE 文件头中的文件特征字段 IMAGE_FILE_DEBUG_STRIPPED 告诉调试器 Codeview 信息已被剥离到单独的 DBG 文件中。

一篇关于COFF格式的知识库文章提到了"dumpbin"工具及其"/SYMBOLS"选项:
/SYMBOLS      Setting this option causes DUMPBIN to display the COFF symbol
              table. Symbol tables exist in all object files. A COFF symbol
              table appears in an image file only if it is linked with
              /DEBUG /DEBUGTYPE:COFF

下一步,也是回答我们问题的部分是:
  • 嵌入式调试信息的格式是什么?
  • 嵌入式调试信息在PE文件中的哪个位置存储?(资源?数据段?)
但回答“无法完成”似乎是不正确的。

另请参阅


1
我认为在 .Net 框架中不可能实现,尽管旧版的 C++ 编译器似乎有嵌入它的方法,但这些方法和其中的信息因编译器和目标调试器而异。 - Nyerguds
Ian,你最终解决了这个C++问题吗? - user541686
@Mehrdad 我根本就没想明白! - Ian Boyd

1

在Visual Studio中,没有内置支持此类操作的功能(至少对于托管语言而言)。.PDB和.EXE文件是同时创建的,并且没有嵌入选项。我甚至不确定.EXE格式是否支持嵌入PDB符号,尽管我可能在这一点上错了。

我唯一能想到的方法是将PDB作为资源嵌入到.EXE中。但是,由于两者是同时构建的,因此必须进行后构建步骤。如果在构建后修改EXE,则有可能使PDB的某些部分无效。

您尝试这样做的特定原因是什么?我想象它最终会给您带来很多痛苦,因为1)据我所知,它不受支持,2)工具链旨在查找同一目录中的PDB,而不是在.EXE内部查找。起初部署两个文件有点麻烦,但目前就是这样做的。


该问题没有提到托管语言。使用编译器选项 /Z7 将调试信息嵌入库中。 - DaveCleland

0

我相信PDB文件一直都是独立的文件。VC++曾经有一个开关,可以使其向“CodeView” .DBG文件发出(与PDB相比较有限的)符号信息,该文件默认情况下嵌入在EXE中。然而,这个开关似乎在新版本的编译器中已不再支持(6.x之后?)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接