在 Visual Studio 调试器中指定符号(.pdb)和源文件(C#、C++、Visual Basic、F#)

程序数据库 (.pdb) 文件(也称为符号文件、映射项目的源代码中的标识符和语句)到已编译应用中的相应标识符和说明。 这些映射文件将调试器链接到源代码,从而启用调试。

使用标准调试生成配置从 Visual Studio IDE 生成项目时,编译器会创建相应的符号文件。 本文介绍如何在 IDE 中管理符号文件,例如:

有关符号文件的详细说明,请参阅 “了解符号文件和 Visual Studio 符号设置”。

符号文件的工作原理

.pdb 文件保存调试和项目状态信息,允许对应用的调试配置进行增量链接。 Visual Studio 调试器使用 .pdb 文件在调试时确定两个关键信息片段:

  • 要显示在 Visual Studio IDE 中的源文件名称和行号
  • 应用中要停止的断点的位置

符号文件还显示源文件的位置,还可以选择显示要从中检索它们的服务器。

调试器仅加载与应用构建时创建的 .pdb 文件完全匹配的 .pdb 文件(即原始 .pdb 文件或其副本)。 此确切重复是必需的,因为即使代码本身未更改,应用布局也会更改。 有关详细信息,请参阅 为什么 Visual Studio 要求调试器符号文件与生成的二进制文件完全匹配?

小窍门

若要在项目源代码外部调试代码(如 Windows 代码或项目调用的第三方代码),必须指定外部代码的 .pdb 文件(以及(可选)源文件的位置,这些文件必须与应用中的生成完全匹配。

调试器搜索符号的地方

在 Visual Studio IDE 中调试项目时,调试器会自动加载默认情况下可以找到的符号文件。

注释

在远程设备上调试托管代码时,所有符号文件必须位于本地计算机上,或位于 调试器选项中指定的位置。

调试器按指定顺序搜索以下位置中的符号文件:

  1. 项目文件夹。

  2. DLL 或可执行文件 (.exe) 文件中指定的位置。

    默认情况下,如果在计算机上生成 DLL 或 .exe 文件,链接器会将关联的 .pdb 文件的完整路径和文件名放在 DLL 或 .exe 文件中。 调试器检查符号文件是否存在于该位置。

  3. 与 DLL 或 .exe 文件相同的文件夹。

  4. 符号文件的调试器选项中指定的任何位置。 若要添加和启用符号位置,请参阅 “配置符号位置和加载选项”。

    • 任何本地符号缓存文件夹。

    • 指定的网络、Internet 或本地符号服务器和位置,例如 Microsoft 符号服务器(如果选择)。 Visual Studio 可以从实现协议的 symsrv 符号服务器下载调试符号文件。 Visual Studio Team Foundation ServerWindows 调试工具 是两种可以使用符号服务器的工具。

      可以使用的符号服务器包括:

      公共Microsoft符号服务器:若要调试调用系统 DLL 或第三方库期间发生的崩溃,通常需要系统 .pdb 文件。 系统 .pdb 文件包含 Windows DLL、 .exe 文件和设备驱动程序的符号。 可以从公共Microsoft符号服务器获取 Windows作系统、MDAC、IIS、ISA 和 .NET 的符号。

      内部网络或本地计算机上的符号服务器:团队或公司可以为自己的产品创建符号服务器,并作为来自外部源的符号的缓存。 你可能自己的计算机上有一个符号服务器。

      第三方符号服务器:Windows 应用程序和库的第三方提供程序可以提供对 Internet 上的符号服务器的访问权限。

警告

如果使用非公共Microsoft符号服务器的符号服务器,请确保符号服务器及其路径可信。 由于符号文件可能包含任意可执行代码,因此你可能会暴露在安全威胁之中。

配置符号文件和加载选项的位置

默认情况下,调试器会检查各种位置中的符号。 有关详细信息,请参阅 调试器查找符号的位置

“工具 ”(或 “调试” >选项 )菜单中,可以访问 “调试>符号 ”选项:

  • 指定并选择符号文件的搜索路径。
  • 为Microsoft、Windows 或第三方组件指定符号服务器。
  • 指定你执行或不希望调试器自动加载符号的模块。
  • 您可以在进行主动调试时更改这些设置。 请参阅调试时加载符号

若要指定符号位置和加载选项,请执行以下作:

  1. 打开 “工具 ”(或 “调试” >选项 )窗格,然后展开“ 所有设置>调试>常规>符号>搜索位置 ”部分。

  2. 在右窗格中,选中每个所需服务器的复选框: Microsoft符号服务器NuGet.org 符号服务器等。

  3. 通过在“符号文件 (.pdb) 位置”组框的工具栏中选择“+ 添加”,添加新的符号服务器位置。

    在文本字段中输入符号服务器或符号位置的 URL(http)、网络共享或本地路径。 语句结束有助于找到正确的格式。

    显示如何在 Visual Studio 中添加新符号服务器位置的屏幕截图。

    注释

    仅搜索指定的文件夹。 必须为要搜索的任何子文件夹添加条目。

    选中 “启用 ”复选框,然后选择“ 保存”。

  4. 通过单击 “新建 Azure DevOps Symbol Server 位置”链接 添加 Azure DevOps Symbol Server 位置。

    “连接到 Azure DevOps 符号服务器 ”对话框中,选择可用的符号服务器,然后选择“ 连接”。

    显示如何在 Visual Studio 中添加新的 Azure DevOps 符号服务器位置的屏幕截图。

    有关详细信息,请参阅 “添加 Azure Artifacts 符号服务器”。

    • 若要更改符号位置的加载顺序,请使用 Ctrl + 向上键和 Ctrl向下 + ,或选择“上移”和“下移”。
    • 若要编辑 URL 或路径,请双击该条目,或突出显示该条目,然后选择“ 编辑”。
    • 若要删除条目,请突出显示该条目,然后选择“ 删除”。
  1. 打开 “工具 ”(或 “调试” >选项 )对话框,然后展开 “调试>符号 ”部分。

  2. “符号文件”(.pdb)搜索位置 组框中,选中每个所需服务器的复选框: Microsoft符号服务器NuGet.org 符号服务器等。

  1. 通过在“符号文件(.pdb)搜索位置”组框的工具栏中选择新建位置 (+) 来添加新的符号服务器位置。

    在文本字段中输入符号服务器或符号位置的 URL(http)、网络共享或本地路径。 语句结束有助于找到正确的格式。

    显示如何添加新符号服务器位置的屏幕截图。

    注释

    仅搜索指定的文件夹。 必须为要搜索的任何子文件夹添加条目。

  1. 通过在“符号文件(.pdb)搜索位置”组框的工具栏中选择“新建位置”来添加新的符号服务器位置。

    在文本字段中输入符号服务器或符号位置的 URL(http)、网络共享或本地路径。 语句结束有助于找到正确的格式。

    显示如何添加新符号服务器位置的动画。

    注释

    仅搜索指定的文件夹。 必须为要搜索的任何子文件夹添加条目。

  1. 通过在组框工具栏中选择 “新建 Azure DevOps 符号服务器位置”来添加新的 Azure DevOps 符号服务器位置

    “连接到 Azure DevOps 符号服务器 ”对话框中,选择可用的符号服务器,然后选择“ 连接”。

    有关详细信息,请参阅 “添加 Azure Artifacts 符号服务器”。

    • 若要更改符号位置的加载顺序,请使用 Ctrl + 向上 键和 Ctrl + 向下键,或选择 向上向下 作。
    • 若要编辑 URL 或路径,请双击该条目,或突出显示该条目,然后按 F2
    • 若要删除某个条目,请突出显示它,然后选择“ 删除位置 ”(-)。
  1. (可选)通过为复制的符号指定本地文件夹路径来提高符号加载性能。

    对于 此目录选项中的缓存符号 ,请输入符号服务器可以将符号复制到的本地文件夹路径。

    注释

    • 不要将本地符号缓存放置在受保护的文件夹中,例如 C:\Windows 或子文件夹。 而应使用可读写的文件夹。

    • 如果设置了 _NT_SYMBOL_PATH 环境变量,该值将覆盖 此目录值中的缓存符号

  2. 指定调试器在启动时要从符号文件 (.pdb) 位置加载的模块。

    1. 更改为“ 所有设置>调试>常规>符号>搜索和加载 ”部分。

    2. 使用下拉列表设置 自动符号搜索 选项的值:

      • 自动选择要搜索的模块符号 (建议):允许 Visual Studio 决定搜索和加载哪些符号。 默认情况下,Visual Studio 会自动加载由打开的解决方案生成的符号,并加载执行常见调试作所需的任何其他符号。 此选项可减少 Visual Studio 必须搜索和加载的文件数,从而提高调试器性能。 可以通过创建 包含的模块列表来强制加载其他符号。

        显示如何选择和配置“自动选择要搜索的模块符号”选项的屏幕截图。

      • 搜索所有模块符号,除非已排除:强制 Visual Studio 加载调试过程中的所有符号。 不建议使用此选项,因为它可能会降低调试体验的速度。 可以通过创建 排除模块列表来强制 Visual Studio 忽略某些符号。

        屏幕截图显示了如何选择和配置“搜索所有模块符号(除非排除)”选项。

    “调试>符号 ”部分中,选择 “符号搜索首选项 ”选项的值:

    显示如何选择和配置符号搜索首选项选项的屏幕截图。

    • 自动选择要搜索的模块符号 (建议):允许 Visual Studio 决定搜索和加载哪些符号。 默认情况下,Visual Studio 会自动加载由打开的解决方案生成的符号,并加载执行常见调试作所需的任何其他符号。 此选项可减少 Visual Studio 必须搜索和加载的文件数,从而提高调试器性能。 可以通过创建 包含的模块列表来强制加载其他符号。

    • 搜索所有模块符号,除非已排除:强制 Visual Studio 加载调试过程中的所有符号。 不建议使用此选项,因为它可能会降低调试体验的速度。 可以通过创建 排除模块列表来强制 Visual Studio 忽略某些符号。

    • 加载所有模块,除非排除 (默认值):加载符号文件位置中所有模块的所有符号,但专门排除的模块除外。

      若要排除某些模块,请选择 “指定排除的模块”。 选择 “添加 ”(+),输入要排除的模块的名称,然后选择“ 确定”。

    • 仅加载指定的模块:仅加载从符号文件位置指定的模块。

      若要标识模块,请选择 “指定包含的模块”。 选择 “添加 ”(+),输入要包括的模块的名称,然后选择“ 确定”。 不会加载其他模块的符号文件。

  1. 若要应用设置,请选择“ 确定”。

指定模块筛选器

通过“自动选择...”“搜索所有...”选项,可以控制调试期间搜索哪些符号。

对于自动选择要搜索的模块符号选项,请通过创建包含的模块列表来指定搜索列表。

显示如何创建包含模块列表的屏幕截图。

  1. 在列表工具栏中选择 “+ 添加 ”。

  2. “添加项 ”对话框中,输入 “模块名称”,选中 “已启用 ”复选框,然后选择“ 保存”。

  3. 根据需要向列表中添加更多项。

通过选择 “指定模块筛选器 ”链接指定搜索列表:

显示如何选择“指定模块筛选器”链接的屏幕截图。

对于 自动选择要搜索的模块符号 选项,会打开自动符号搜索首选项对话框:

指定模块筛选器的屏幕截图。

若要创建 “模块”筛选器 列表,请选择“ 新建模块 ”(+),输入新模块,然后选择“ 确定”。

模块筛选器支持简单的通配符匹配。 星号 * 与任意组字符匹配。 例如, *myproduct* 匹配 myproduct.utilities.dllentrypoint.myproduct.exe等文件。

可以配置其他选项来自定义体验:

  • 始终加载位于模块旁的符号:Visual Studio 加载存储在文件系统中的 .pdb 文件及其相应的 .dll.exe 文件。 此方法非常有用,例如尝试调试已部署的 Web 应用时。

  • 根据需要自动加载其他符号:Visual Studio 搜索符号以执行常见的调试作,例如单步执行,即使要单步执行的模块不在项目或模块筛选器中。 确定搜索的方式可能会受到 “仅我的代码 ”设置的影响。

对于搜索所有模块符号(除非排除)选项,通过创建排除的模块列表来指定搜索范围。

显示如何创建排除模块列表的屏幕截图。

  1. 在列表工具栏中选择 “+ 添加 ”。

  2. “添加项 ”对话框中,输入 “模块名称”,选中 “已启用 ”复选框,然后选择“ 保存”。

  3. 根据需要向列表中添加更多项。

对于“搜索所有模块符号,除非排除”选项,将打开“符号排除首选项”对话框。

指定排除的模块的屏幕截图。

若要创建 “模块”筛选器 列表,请选择“ 新建模块 ”(+),输入新模块,然后选择“ 确定”。

在此对话框中,可以选择 不希望 Visual Studio 加载符号的模块。 在此方案中,除非添加匹配筛选器来排除它们,否则 Visual Studio 会尝试加载调试过程中每个模块的符号(包括非Microsoft方提供的模块)。 只有通过您的“仅我的代码”设置才能修改此行为。

用于调试的其他符号选项

可以从“工具”(或“调试”>选项)菜单中选择更多调试符号选项

所有设置>>”部分中提供了以下设置

调试>常规 ”部分提供了以下设置。

  • 加载 dll 导出(仅限本机):加载 C/C++的 DLL 导出表。 有关详细信息,请参阅 DLL 导出表。 读取 DLL 导出信息涉及一些开销,因此默认情况下会关闭加载导出表。 也可以在 C/C++生成命令行中使用 dumpbin /exports

  • 启用地址级调试如果源不可用,则显示反汇编:在找不到源代码或符号文件时始终显示反汇编。

  • 启用源服务器支持:当本地计算机上没有源代码或 .pdb 文件与源代码不匹配时,使用源服务器帮助调试应用。 源服务器接受对文件的请求,并从源代码管理返回实际文件。 源服务器使用名为 srcsrv.dll 的 DLL 运行,以读取应用的 .pdb 文件。 .pdb 文件包含指向源代码存储库的指针,以及用于从存储库检索源代码的命令。

    可以通过在名为 srcsrv.ini的文件中列出允许的命令来限制 srcsrv.dll 可从应用的 .pdb 文件中执行的命令。 将 srcsrv.ini 文件放置在 与srcsrv.dlldevenv.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 选项设置为创建名为 的 < 文件。

    如果使用生成文件生成 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 文件的路径。

  • DLL 导出表

    用于 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 会在开始调试时自动设置此设置。

调试时加载符号

可以在调试时使用 模块调用堆栈局部变量自动或任何 监视 窗口加载符号或更改符号选项。 有关详细信息,请参阅熟悉调试器如何附加到应用

在“模块”窗口中使用符号

在调试期间,“ 模块” 窗口显示调试器正在视为用户代码或“我的代码”及其符号加载状态的代码模块。 还可以在 “模块” 窗口中监视符号加载状态、加载符号和更改符号选项。

在调试时监视或更改符号位置或选项:

  1. 若要在调试时打开 “模块 ”窗口,请选择 “调试>Windows>模块 ”(或按 Ctrl + Alt + U)。

  2. 在“ 模块 ”窗口中,右键单击 “符号状态 ”或“ 符号文件” 标头或任何模块。

  3. 在上下文菜单中,选择以下选项之一:

    选项 DESCRIPTION
    加载符号 对于具有跳过、未找到或未加载符号的模块显示。 尝试从“工具>选项”窗格中的“所有设置>调试>符号搜索和加载或>”部分下指定的位置加载符号。 如果未找到或未加载符号文件,请启动 文件资源管理器 ,以便可以指定要搜索的新位置。
    符号加载信息 显示加载的符号文件的位置,或调试器找不到文件时搜索的位置。
    符号设置 “工具>选项 ”窗格打开到“ 所有设置>调试>符号>搜索位置 ”部分,可在其中编辑和添加符号位置。
    始终自动加载 将所选符号文件添加到调试器自动加载的文件列表中。
    将源反编译为符号文件 对于 .NET 代码,可以选择此选项,然后按照 生成和嵌入程序集源中的说明进行作。
    选项 DESCRIPTION
    加载符号 对于具有跳过、未找到或未加载符号的模块显示。 尝试从工具>选项对话框中的调试>符号部分中指定的位置加载符号。 如果未找到或未加载符号文件,请启动 文件资源管理器 ,以便可以指定要搜索的新位置。
    符号加载信息 显示加载的符号文件的位置,或调试器找不到文件时搜索的位置。
    符号设置 打开“ 工具>选项 ”对话框,指向 “调试>符号 ”部分,可在其中编辑和添加符号位置。
    始终自动加载 将所选符号文件添加到调试器自动加载的文件列表中。
    将源反编译为符号文件 对于 .NET 代码,可以选择此选项,然后按照 生成和嵌入程序集源中的说明进行作。

使用“未加载符号/未加载源”页面

调试器可以通过多种方式进入没有符号或源文件的代码中:

  • 单步执行代码。
  • 通过断点或异常中断代码。
  • 切换到其他线程。
  • 通过在 “调用堆栈 ”窗口中双击帧来更改堆栈帧。

发生这种情况时,调试器将显示 “未加载符号 ”或 “无源加载 ”页,以帮助查找和加载必要的符号或源。

“未加载符号”页的屏幕截图。

若要使用“未加载符号文档”页以协助查找和加载缺失的符号:

  • 若要更改搜索路径,请选择未选择的路径,或选择 “新建路径 ”或“ 新建 VSTS 路径 ”,然后输入或选择新路径。 选择 “加载 ”以再次搜索路径,并在找到符号文件时加载符号文件。

  • 为了覆盖任何符号选项并重试搜索路径,请选择 “浏览”并找到 <可执行文件名称>。 如果找到符号文件则加载,否则打开文件资源管理器以便您手动选择符号文件。

  • 若要打开符号设置页以配置行为,请选择“ 更改符号设置 ”(或打开 “工具>选项 ”窗格,然后转到“ 所有设置>调试>符号>搜索和加载搜索位置 ”部分)。
  • 若要打开符号设置页以配置行为,请选择“ 更改符号设置 ”(或打开 “工具>选项 ”对话框,然后转到 “调试>符号 ”部分)。
  • (高级)若要一次在新窗口中显示反汇编,请选择 视图反汇编,或选择“ 选项”对话框 ,以设置在找不到源或符号文件时始终显示反汇编的选项。 有关详细信息,请参阅 “查看反汇编代码”。

  • 若要显示搜索的位置和结果,请展开 符号加载信息

  • 对于 C# 代码,还可以选择从“未加载符号”或“无源加载”页中反编译源代码

如果在执行其中一个选项后调试器找到 .pdb 文件,并且可以使用 .pdb 文件中的信息检索源文件,则会显示源。 否则,它会显示 无源加载 页,描述问题,并包含可能解决该问题的操作链接。

若要向解决方案添加源文件搜索路径,请执行以下作:

可以指定调试器搜索源文件的位置,并从搜索中排除特定文件。

  1. 解决方案资源管理器中选择解决方案,然后选择 “属性” 图标,按 Alt+Enter,或右键单击并选择“ 属性”。

  2. 选择 “调试源文件”。

    “调试源文件”页

  3. 包含源代码的目录下,键入或选择要搜索的源代码位置。 使用 “新建线条 ”图标可以添加更多位置、 向上向下 箭头图标来重新排序它们,或者 使用 X 图标将其删除。

    注释

    调试器仅搜索指定的目录。 必须为要搜索的任何子目录添加条目。

  4. “不查找这些源文件”下,键入要从搜索中排除的源文件的名称。

  5. 选择 “确定”“应用”。