程序数据库 (.pdb) 文件(也称为符号文件、映射项目的源代码中的标识符和语句)到已编译应用中的相应标识符和说明。 这些映射文件将调试器链接到源代码,从而启用调试。
使用标准调试生成配置从 Visual Studio IDE 生成项目时,编译器会创建相应的符号文件。 本文介绍如何在 IDE 中管理符号文件,例如:
有关符号文件的详细说明,请参阅以下内容:
符号文件的工作原理
.pdb 文件保存调试和项目状态信息,允许对应用的调试配置进行增量链接。 Visual Studio 调试器使用 .pdb 文件在调试时确定两个关键信息片段:
- 要在 Visual Studio IDE 中显示的源文件名和行号。
- 在应用中停止的断点位置。
符号文件还显示源文件的位置,还可以选择显示要从中检索它们的服务器。
调试器仅加载与应用构建时创建的 .pdb 文件完全匹配的 .pdb 文件(即原始 .pdb 文件或其副本)。 此确切重复是必需的,因为即使代码本身没有更改,应用布局也会更改。 有关详细信息,请参阅 为什么 Visual Studio 要求调试器符号文件与生成的二进制文件完全匹配?
小窍门
若要在项目源代码外部调试代码(如 Windows 代码或项目调用的第三方代码),必须指定外部代码的 .pdb 文件(以及(可选)源文件的位置,这些文件必须与应用中的生成完全匹配。
调试器搜索符号的地方
在 Visual Studio IDE 中调试项目时,调试器会自动加载默认情况下可以找到的符号文件。
注释
在远程设备上调试托管代码时,所有符号文件必须位于本地计算机上,或位于 调试器选项中指定的位置。
调试器在以下位置搜索符号文件:
项目文件夹。
DLL 或可执行文件 (.exe) 文件中指定的位置。
默认情况下,如果在计算机上生成 DLL 或 .exe 文件,链接器会将关联的 .pdb 文件的完整路径和文件名放在 DLL 或 .exe 文件中。 调试器检查符号文件是否存在于该位置。
与 DLL 或 .exe 文件相同的文件夹。
符号文件的调试器选项中指定的任何位置。 若要添加和启用符号位置,请参阅 “配置符号位置和加载选项”。
任何本地符号缓存文件夹。
指定的网络、Internet 或本地符号服务器和位置,例如 Microsoft 符号服务器(如果选择)。 Visual Studio 可以从实现协议的
symsrv
符号服务器下载调试符号文件。 Visual Studio Team Foundation Server 和 Windows 调试工具 是两种可以使用符号服务器的工具。可以使用的符号服务器包括:
公共Microsoft符号服务器:若要调试调用系统 DLL 或第三方库期间发生的崩溃,通常需要系统 .pdb 文件。 系统 .pdb 文件包含 Windows DLL、 .exe 文件和设备驱动程序的符号。 可以从公共Microsoft符号服务器获取 Windows作系统、MDAC、IIS、ISA 和 .NET 的符号。
内部网络或本地计算机上的符号服务器:团队或公司可以为自己的产品创建符号服务器,并作为来自外部源的符号的缓存。 你可能自己的计算机上有一个符号服务器。
第三方符号服务器:Windows 应用程序和库的第三方提供程序可以提供对 Internet 上的符号服务器的访问权限。
警告
如果使用非公共Microsoft符号服务器的符号服务器,请确保符号服务器及其路径可信。 由于符号文件可能包含任意可执行代码,因此你可能会暴露在安全威胁之中。
配置符号文件和加载选项的位置
默认情况下,调试器会检查各种位置中的符号。 请参阅 调试器查找符号的位置。
在 “工具>选项>调试>符号 ”页上,可以:
- 指定并选择符号文件的搜索路径。
- 为Microsoft、Windows 或第三方组件指定符号服务器。
- 指定你执行或不希望调试器自动加载符号的模块。
- 在主动调试时更改这些设置。 请参阅调试时加载符号。
若要指定符号位置和加载选项,请执行以下作:
注释
这些选项已在 Visual Studio 2022 版本 17.12 预览版 1 中更新。
在 Visual Studio 中,打开 工具>选项>调试>符号 (或 调试>选项>符号)。
在“符号文件(.pdb)位置”下,
若要使用 Microsoft符号服务器 或 NuGet.org 符号服务器,请选中该复选框。
若要添加新符号服务器位置,请执行以下步骤:
- 选择 + 工具栏中的符号。
- 在文本字段中键入符号服务器或符号位置的 URL(http)、网络共享或本地路径。 语句结束有助于找到正确的格式。
注释
仅搜索指定的文件夹。 必须为要搜索的任何子文件夹添加条目。
若要添加新的 Azure DevOps 符号服务器位置,请执行以下操作:
选择工具栏中的
图标。
在 “连接到 Azure DevOps 符号服务器 ”对话框中,选择一个可用的符号服务器,然后选择“ 连接”。
有关详细信息,请参阅 “添加 Azure Artifacts 符号服务器”。
若要更改符号位置的加载顺序,请使用 Ctrl+向上键和 Ctrl向下键+或向上键和向下箭头图标。
若要编辑 URL 或路径,请双击该条目,或将其选中并按 F2。
若要删除某个条目,请选择该条目,然后选择 - 图标。
(可选)若要提高符号加载性能, 请在此目录中的缓存符号下,键入符号服务器可复制符号到的本地文件夹路径。
注释
不要将本地符号缓存放置在受保护的文件夹中,如 C:\Windows 或子文件夹。 而应使用可读写的文件夹。
注释
如果设置了 _NT_SYMBOL_PATH
环境变量,它将覆盖 在此目录中的缓存符号下设置的值。
指定您希望调试器在启动时从 符号文件 (.pdb) 位置 加载的模块。
选择“ 自动选择要搜索的模块符号 ”(建议)以允许 Visual Studio 决定要搜索和加载哪些符号。 默认情况下,Visual Studio 会自动加载由打开的解决方案生成的符号,并加载执行常见调试作所需的任何其他符号。 这减少了 Visual Studio 必须搜索和加载的文件数,从而提高调试器性能。 可以通过单击 “指定模块筛选器 ”链接来强制加载其他符号。
选择“搜索所有模块符号”,除非排除以强制 Visual Studio 加载调试过程中的所有符号。 不建议这样做,因为它可能会降低调试体验的速度。 如果选择此选项,可以通过单击 “指定模块筛选器 ”链接来强制 Visual Studio 忽略某些符号。
选择“加载所有模块”(除非已排除(默认值),以加载符号文件位置中所有模块的所有符号,但专门排除的模块除外。 若要排除某些模块,请选择 “指定排除的模块”,选择 + 图标,键入要排除的模块的名称,然后选择“ 确定”。
若要仅加载从符号文件位置指定的模块,请选择 “仅加载指定的模块”。 选择 “指定包含的模块”,选择 + 图标,键入要包括的模块的名称,然后选择“ 确定”。 不会加载其他模块的符号文件。
选择“ 确定”。
指定模块筛选器
“自动选择要搜索的模块符号”和“除非排除,否则搜索所有模块符号”的选项使您可以更精细地控制调试时要搜索哪些符号。 选择 “指定模块筛选器 ”以微调体验。
默认情况下,当 “自动选择要搜索的模块符号 ”处于选中状态时,会看到以下对话框:
可以使用“+”图标将模块添加到筛选器。 模块筛选器支持简单的通配符匹配。 “*”匹配任意组字符。 例如,“*myproduct*”将匹配“myproduct.utilities.dll”和“entrypoint.myproduct.exe”等文件。
还有几种其他选项可以进一步自定义体验:
始终加载位于模块旁边的符号 ,指示 Visual Studio 加载存储在文件系统中的 pdb 文件,这些文件位于其相应的 .dll 或 .exe 文件旁边。 例如,尝试调试已部署的 Web 应用时,这非常有用。
在需要时自动加载其他符号 ,指示 Visual Studio 搜索符号以执行常见的调试作,例如单步执行,即使要单步执行的模块不在项目或模块筛选器中。 确定搜索的方式可能会受到“仅我的代码”设置的影响。
如果您选择了“搜索所有模块符号,除非排除”,则模块筛选器对话框如下所示:
在此对话框中,可以选择 不希望 Visual Studio 加载符号的模块。 在这种情况下,Visual Studio 会尝试为正在调试的进程中的每个模块(包括第三方模块)加载符号,除非您添加匹配的筛选器来排除它们。 修改此行为的唯一其他方法是通过“仅我的代码”设置。
用于调试的其他符号选项
可以在工具>选项>调试>常规(或调试>选项常规)中选择其他符号选项>:
加载 dll 导出(限本地)
加载 C/C++的 DLL 导出表。 有关详细信息,请参阅 DLL 导出表。 读取 DLL 导出信息涉及一些开销,因此默认情况下会关闭加载导出表。 也可以在 C/C++生成命令行中使用
dumpbin /exports
。启用地址级调试 并且在源不可用时显示反汇编
无法找到源或符号文件时,始终显示反汇编。
启用源服务器支持
当本地计算机上没有源代码或 .pdb 文件与源代码不匹配时,使用源服务器来帮助调试应用。 源服务器接受对文件的请求,并从源代码管理返回实际文件。 源服务器使用名为 srcsrv.dll 的 DLL 运行,以读取应用的 .pdb 文件。 .pdb 文件包含指向源代码存储库的指针,以及用于从存储库检索源代码的命令。
可以通过在名为 srcsrv.ini的文件中列出允许的命令来限制 srcsrv.dll 可从应用的 .pdb 文件中执行的命令。 将 srcsrv.ini 文件放置在 与srcsrv.dll 和 devenv.exe相同的文件夹中。
重要
任意命令可以嵌入到应用的 .pdb 文件中,因此请确保仅将要执行的命令放入 srcsrv.ini 文件中。 任何尝试执行不在 srcsvr.ini 文件中的命令都会导致出现确认对话框。 有关详细信息,请参阅 安全警告:调试器必须执行不受信任的命令。
不会对命令参数执行验证,因此请谨慎使用受信任的命令。 例如,如果在srcsrv.ini中列出了 cmd.exe ,恶意 用户可能会在 cmd.exe 上指定参数,使其变得危险。
选择此项和所需的子项。 允许源服务器用于部分信任程序集(仅托管) 和 始终运行不受信任的源服务器命令,而无需提示 可能会增加安全风险。
编译器符号选项
使用标准 调试 生成配置从 Visual Studio IDE 生成项目时,C++托管编译器会为代码创建相应的符号文件。 还可以在代码中设置编译器选项。
若要在 Visual Studio 中设置生成配置的编译器选项,请参阅 “设置调试和发布配置”。
.NET 选项
使用 /debug 构建以生成 .pdb 文件。 可以使用 /debug:full 或 /debug:pdbonly 生成应用程序。 使用 /debug:full 生成可调试代码。 使用 /debug:pdbonly 进行生成可以生成 .pdb 文件,但不会生成通知 JIT 编译器调试信息可用的 DebuggableAttribute
。 如果要为不希望调试的发布版本生成 .pdb 文件,请使用 /debug:pdbonly。 有关详细信息,请参阅 /debug(C# 编译器选项)或 /debug (Visual Basic)。
C/C++ 选项
VC<x>.pdb 和 <project>.pdb 文件
使用 /ZI 或 /Zi 生成时,会创建用于 C/C++的 .pdb 文件。 在 Visual C++中, /Fd 选项命名编译器创建的 .pdb 文件。 使用 IDE 在 Visual Studio 中创建项目时,/Fd 选项设置为创建名为 <project.pdb> 的 .pdb 文件。
如果使用生成文件生成 C/C++应用程序,并且指定 /ZI 或 /Zi 而不使用 /Fd 指定文件名,编译器将创建两个 .pdb 文件:
VC<x.pdb>,其中 <x> 表示 Microsoft C++ 编译器的版本,例如 VC11.pdb
VC<x.pdb> 文件存储单个对象文件的所有调试信息,并驻留在项目生成文件所在的同一目录中。 每次创建对象文件时,C/C++编译器都会将调试信息合并到 VC<x.pdb> 中。 因此,即使每个源文件都包含常见的头文件(如 <windows.h>),这些标头中的 typedefs 仅存储一次,而不是存储在每个对象文件中。 插入的信息包括类型信息,但不包括符号信息,例如函数定义。
<project>.pdb
<project.pdb> 文件存储项目 .exe 文件的所有调试信息,并驻留在 \debug 子目录中。 <project.pdb> 文件包含完整的调试信息,包括函数原型,而不仅仅是 VC<x.pdb> 中找到的类型信息。
VC<x.pdb> 和 <project.pdb> 文件都允许增量更新。 链接器还会在创建.exe 或 .dll 文件中嵌入 .pdb 文件的路径。
-
用于
dumpbin /exports
查看 DLL 导出表中可用的符号。 DLL 导出表中的符号信息有助于处理 Windows 消息、Windows 过程 (WindowProc)、COM 对象、封送或不具有其符号的任何 DLL。 符号可用于任何 32 位系统 DLL。 调用顺序列出,当前函数(最深层嵌套)位于顶部。通过读取
dumpbin /exports
输出,可以看到确切的函数名称,包括非字母数字字符。 查看确切的函数名称对于在函数上设置断点很有用,因为可以在调试器中的其他位置截断函数名称。 有关详细信息,请参阅 dumpbin /exports。
Web 应用程序
将 ASP.NET 应用程序的web.config文件设置为调试模式。 调试模式会导致 ASP.NET 为动态生成的文件生成符号,并使调试器能够附加到 ASP.NET 应用程序。 如果从 Web 项目模板创建项目,Visual Studio 会在开始调试时自动设置此设置。
调试时加载符号
可以在调试时使用 模块、 调用堆栈、 局部变量、 自动或任何 监视 窗口加载符号或更改符号选项。 有关详细信息,请参阅熟悉调试器如何附加到应用。
在“模块”窗口中使用符号
在调试期间,“ 模块” 窗口显示调试器正在视为用户代码或“我的代码”及其符号加载状态的代码模块。 还可以在 “模块” 窗口中监视符号加载状态、加载符号和更改符号选项。
在调试时监视或更改符号位置或选项:
- 若要在调试时打开 “模块 ”窗口,请选择 “调试>Windows>模块 ”(或按 Ctrl + Alt + U)。
- 在“ 模块 ”窗口中,右键单击 “符号状态 ”或“ 符号文件” 标头或任何模块。
- 在上下文菜单中,选择以下选项之一:
选项 | DESCRIPTION |
---|---|
加载符号 | 对于具有跳过、未找到或未加载符号的模块显示。 尝试从选项>调试>页面上指定的位置加载符号。 如果未找到或未加载符号文件,请启动 文件资源管理器 ,以便可以指定要搜索的新位置。 |
符号加载信息 | 显示加载的符号文件的位置,或调试器找不到文件时搜索的位置。 |
符号设置 | 打开 “选项>调试>符号 ”页,可在其中编辑和添加符号位置。 |
始终自动加载 | 将所选符号文件添加到调试器自动加载的文件列表中。 |
将源反编译为符号文件 | 对于 .NET 代码,可以选择此选项,然后按照 生成和嵌入程序集源中的说明进行作。 |
使用“未加载符号/未加载源”页面
调试器可通过多种方式中断没有可用符号或源文件的代码:
- 单步执行代码。
- 通过断点或异常中断代码。
- 切换到其他线程。
- 通过在 “调用堆栈 ”窗口中双击帧来更改堆栈帧。
发生这种情况时,调试器将显示 “未加载符号 ”或 “无源加载 ”页,以帮助查找和加载必要的符号或源。
若要使用“未加载符号文档”页以协助查找和加载缺失的符号:
- 若要更改搜索路径,请选择未选择的路径,或选择 “新建路径 ”或“ 新建 VSTS 路径 ”,然后输入或选择新路径。 选择 “加载 ”以再次搜索路径,并在找到符号文件时加载符号文件。
- 为了覆盖任何符号选项并重试搜索路径,请选择 “浏览”并找到 <可执行文件名称>。 找到符号文件时会加载,如果找不到,文件资源管理器将打开以便您手动选择符号文件。
- 若要打开符号设置页以配置行为,请选择 “更改符号设置 ”(或选择 “选项>调试>符号”)。
- (高级)若要一次在新窗口中显示反汇编,请选择 视图反汇编,或选择“ 选项”对话框 ,以设置选项,以在找不到源或符号文件时始终显示反汇编。 有关详细信息,请参阅 “查看反汇编代码”。
- 若要显示搜索的位置和结果,请展开 符号加载信息。
- 对于 C# 代码,还可以选择从“未加载符号”或“无源加载”页中反编译源代码。
如果在执行其中一个选项后调试器找到 .pdb 文件,并且可以使用 .pdb 文件中的信息检索源文件,则会显示源。 否则,它会显示 无源加载 页,描述问题,并包含可能解决该问题的操作链接。
若要向解决方案添加源文件搜索路径,请执行以下作:
可以指定调试器搜索源文件的位置,并从搜索中排除特定文件。
在 解决方案资源管理器中选择解决方案,然后选择 “属性” 图标,按 Alt+Enter,或右键单击并选择“ 属性”。
选择 “调试源文件”。
在 包含源代码的目录下,键入或选择要搜索的源代码位置。 使用 “新建线条 ”图标可以添加更多位置、 向上 和 向下 箭头图标来重新排序它们,或者 使用 X 图标将其删除。
注释
调试器仅搜索指定的目录。 必须为要搜索的任何子目录添加条目。
在 “不查找这些源文件”下,键入要从搜索中排除的源文件的名称。
选择 “确定” 或 “应用”。