SymSrv 的高级用法

SymSrv 可以从中央符号存储中传送符号文件。 此存储可以包含任意数量的符号文件,对应任意数量的程序或操作系统。 存储还可以包含二进制文件(在调试微型转储时非常有用)。

存储可以包含实际符号和二进制文件,也可以只包含指向符号文件的指针。 如果存储包含指针,SymSrv 将直接从文件源检索实际文件。

SymSrv 还可用于将大型符号存储区分隔为适合专用调试任务的较小子集。

最后,SymSrv 可以使用操作系统提供的登录信息从 HTTP 或 HTTPS 源获取符号文件。 SymSrv 支持受智能卡、证书以及常规登录名和密码保护的 HTTPS 站点。 有关详细信息,请参阅 HTTP 符号存储

设置符号路径

若要使用此符号服务器,symsrv.dll 必须与调试器安装在同一目录下。 可以按以下代码所示设置符号路径:

set _NT_SYMBOL_PATH = symsrv*ServerDLL*DownstreamStore*\\Server\Share

set _NT_SYMBOL_PATH = symsrv*ServerDLL*\\Server\Share

set _NT_SYMBOL_PATH = srv*DownstreamStore*\\Server\Share

set _NT_SYMBOL_PATH = srv*\\Server\Share

此语法的各个部分说明如下:

symsrv
此关键字必须始终首先显示。 它向调试器表明,此项是符号服务器,而不仅仅是普通的符号目录。

ServerDLL
指定符号服务器 DLL 的名称。 如果使用 SymSrv 符号服务器,则始终为 symsrv.dll。

srv
这是 symsrv*symsrv.dll 的简写。

DownstreamStore
指定下游存储。 这是用于缓存单个符号文件的本地目录或网络共享。

可以指定多个下游存储,用星号分隔。 此页下方的级联下游存储中解释了多个下游存储。

如果在通常指定下游存储的行中包含两个星号,则使用默认的下游存储。 此存储将位于主目录的符号子目录中。 主目录默认为调试器安装目录;这可以通过使用 !homedir 扩展或设置DBGHELP_HOMEDIR 环境变量来更改。

如果 DownstreamStore 指定不存在的目录,SymStore 将尝试创建它。

如果省略了 DownstreamStore 参数并且不包含额外的星号,换句话说,如果使用仅带一个星号的 srv 或仅带有两个星号的 symsrv,则不会创建任何下游存储。 调试器将直接从服务器加载所有符号文件,而不在本地缓存它们。

注意 :如果要从 HTTP 或 HTTPS 站点访问符号,或者符号存储使用压缩文件,则始终使用下游存储。 如果未指定下游存储,则会在主目录的符号子目录中创建一个。

\\Server\Share
指定远程符号存储的服务器和共享。

如果使用下游存储,调试器将首先在此存储中查找符号文件。 如果未找到符号文件,调试器将从指定的 服务器共享中找到符号文件,然后在下游存储中缓存此文件的副本。 该文件将复制到 DownstreamStore 下树中的子目录,该子目录对应于其在 \\Server\Share 下树中的位置。

符号服务器不必是符号路径中唯一的条目。 如果符号路径由多个条目组成,则无论命名的是符号服务器还是实际目录,调试器都会按顺序(从左到右)检查所需符号文件的每个条目。

下面是一些示例。 若要将 SymSrv 用作符号服务器并在 \\mybuilds\mysymbols 上存储符号,请设置以下符号路径:

set _NT_SYMBOL_PATH= symsrv*symsrv.dll*\\mybuilds\mysymbols

若要设置符号路径以便调试器将符号文件从 \\mybuilds\mysymbols 上的符号存储复制到本地目录 c:\localsymbols,请使用:

set _NT_SYMBOL_PATH=symsrv*symsrv.dll*c:\localsymbols*\\mybuilds\mysymbols

若要设置符号路径以便调试器将符号文件从 HTTPS 站点复制到https://www.company.com/manysymbols本地网络目录 \\localserver\mycache,请使用:

set _NT_SYMBOL_PATH=symsrv*symsrv.dll*\\localserver\myshare\mycache*https://www.company.com/manysymbols

最后一个示例也可以缩短:

set _NT_SYMBOL_PATH=srv*\\localserver\myshare\mycache*https://www.company.com/manysymbols

此外,符号路径可以包含多个目录或符号服务器,用分号分隔。 这样就可以从多个位置(甚至多个符号服务器)查找符号。 如果二进制文件的符号文件不匹配,则调试器无法使用符号服务器找到它,因为它仅检查确切参数。 但是,调试器可能会使用传统符号路径找到名称正确的不匹配符号文件,并成功加载它。 尽管文件在技术上不是正确的符号文件,但它可能提供有用的信息。

删除缓存

如果使用 DownstreamStore 作为缓存,可以随时删除此目录以节省磁盘空间。

可以拥有一个庞大的符号存储区,其中包含许多不同程序或 Windows 版本的符号文件。 如果升级目标计算机上使用的 Windows 版本,则缓存的符号文件将全部与早期版本匹配。 这些缓存的文件不会再使用,因此这可能是删除缓存的好时机。

级联下游存储

可以指定任意数量的下游存储,用星号分隔。 这些存储称为级联符号存储

初始 srv*symsrv*ServerDLL*之后,每个后续标记表示符号位置。 首先检查最左边的标记。 空标记(由一行中的两个星号或字符串末尾的星号表示)表示默认的下游存储。

下面是一个符号路径示例,该路径使用两个下游存储来保存正在访问的主符号存储中的信息。 这些可以称为主存储、中级存储和本地缓存:

srv*c:\localcache*\\interim\store*https://msdl.microsoft.com/download/symbols

在此方案中,SymSrv 将首先在 c:\localcache 中查找符号文件。 如果在那里找到它,它将返回一个路径。 如果未在那里找到,它将在 \\interim\store 中查找。 如果在那里找到符号文件,SymSrv 会将其复制到 c:\localcache 并返回路径。 如果未在那里找到,SymSrv 将在 Microsoft 公共符号存储https://msdl.microsoft.com/download/symbols查找;如果找到该文件,SymSrv 会将该文件复制到 \\interim\store 和 c:\localcache。

使用以下路径可以获取类似的行为:

srv**\\interim\store*https://internetsite

在这种情况下,本地缓存是默认的下游存储,主存储是 Internet 站点。 指定了 \\interim\store 的中级存储区在其他两个存储之间使用。

当 SymSrv 处理包含级联存储的路径时,它将跳过无法读取或写入的任何存储。 因此,如果共享出现故障,它会将文件从缺失存储区复制到下游存储区,而不会出现任何错误。 此错误的一个很好的副作用是,只要主存储不可写,用户就可以指定多个主存储来提供单个下游存储流。

从主存储中检索压缩符号文件时,它将以压缩形式存储在任何中级存储中。 该文件将在路径的最底部存储区中解压缩。

使用 HTTP 和 SMB 符号服务器路径

如前所述,链接(或级联)是指在符号路径中每个“*”分隔符之间进行的复制。 符号按从左到右的顺序搜索。 每次未命中时,将查询下一个(上游)符号服务器,直到找到该文件。

如果找到该文件,则会将文件从(上游)符号服务器复制到上一个(下游)符号服务器。 对于每个(下游)符号服务器,都会重复此操作。 通过这种方式,(共享)下游符号服务器将由使用符号服务器的所有客户端的集体努力进行填充。

即使可以在没有 SRV* 前缀的情况下使用链接的 UNC 路径,但我们建议指定 SRV* 以便使用 symsrv.dll 的高级错误处理。

在路径中包含 HTTP 符号服务器时,只能指定一个(每个链),并且它必须位于路径的末尾(因为它无法写入以用作缓存)。 如果基于 HTTP 的符号存储位于存储列表的中间或左侧,则无法将任何找到的文件复制到其中,并且链将断开。 此外,由于符号处理程序无法从网站打开文件,因此基于 HTTP 的存储不应是列表最左侧或唯一的存储。 如果 SymSrv 曾出现过此符号路径,它将尝试通过将文件复制到默认的下游存储并将其从该位置打开来恢复,无论符号路径中是否指示默认下游存储。

仅当使用 SRV* 前缀(由 symsrv.dll 符号处理程序实现)时,才支持 HTTP。

HTTP 和 SMB 共享符号服务器方案示例

常见的仅 UNC 部署涉及托管所有文件的中央办公室 (\\MainOffice\Symbols)、缓存子集的分支机构 (\\BranchOfficeA\Symbols) 和缓存其引用的文件桌面 (C:\Symbols)。

srv*C:\Symbols*\\BranchOfficeA\Symbols*\\MainOffice\Symbols

当 SMB 共享是主要(上游)符号存储时,需要读取。

srv*C:\Symbols*\\MachineName\Symbols

当 SMB 共享是中间(下游)符号存储时,需要读取/更改。 客户端会将文件从主符号存储复制到 SMB 共享,然后从 SMB 共享复制到本地文件夹。

srv*C:\Symbols*\\MachineName\Symbols*https://msdl.microsoft.com/download/symbols
srv*C:\Symbols*\\MachineName\Symbols*\\MainOffice\Symbols

当 SMB 共享是 SymProxy 部署中的中间(下游)符号存储时,只需要读取。 SymProxy ISAPI 筛选器将执行写入操作,而不是客户端。

srv*C:\Symbols*\\MachineName\Symbols*https://SymProxyName/Symbols

多个 HTTP 和 SMB 共享符号服务器缓存方案

可以指定多个符号服务器链和缓存位置,用分号“;”分隔。 如果符号位于第一个链中,则不会遍历第二个链。 如果符号不在第一个链中,将遍历第二个链;如果符号位于第二个链中,则会将其缓存在指定位置。 如果符号在第一个链中指定的主符号服务器上不可用,此方法将允许正常使用主符号服务器,并且仅使用辅助服务器。

srv*C:\Symbols*\\Machine1\Symbols*https://SymProxyName/Symbols;srv*C:\WebSymbols*https://msdl.microsoft.com/download/symbols

cache*localsymbolcache

创建符号本地缓存的另一种方法是使用符号路径中的 cache*localsymbolcache 字符串。 这不是符号服务器元素的一部分,而是符号路径中的单独元素。 调试器将使用指定的目录 localsymbolcache 来存储从此字符串右侧的符号路径中出现的任何元素加载的任何符号。 这允许您对从任何位置下载的符号使用本地缓存,而不仅仅是符号服务器下载的符号。

例如,以下符号路径不会缓存从 \\someshare 获取的符号。 它将使用 c:\mysymbols 缓存从 \\anothershare 获取的符号,因为以 \\anothershare 开头的元素显示在 cache*c:\mysymbols 元素右侧。 它还将使用 c:\mysymbols 来缓存从 Microsoft 公共符号存储中获取的符号,因为符号服务器使用的是通常语法(srv 包含两个或多个星号)。 此外,如果随后使用 .sympath+ 命令将其他位置添加到此路径,这些新元素也将被缓存,因为它们将会追加到路径的右侧。

_NT_SYMBOL_PATH=\\someshare\that\cachestar\ignores;srv*c:\mysymbols*https://msdl.microsoft.com/download/symbols;cache*c:\mysymbols;\\anothershare\that\gets\cached

How SymSrv Locates Files

SymSrv 创建所需符号文件的完全限定 UNC 路径。 此路径以 _NT_SYMBOL_PATH 环境变量中记录的符号存储路径开始。 SymbolServer 例程用于标识所需文件的名称;此名称作为目录名称追加到路径中。 然后追加另一个目录名称,由传递给 SymbolServerID23 个参数的串联组成。 如果其中任何值为零,则省略这些值。

在结果目录中搜索符号文件或符号存储指针文件。

如果此搜索成功,SymbolServer 会将路径传递给调用方并返回 TRUE。 如果未找到该文件,则 SymbolServer 返回 FALSE

使用 AgeStore 减少缓存大小

AgeStore 工具可用于删除早于指定日期的缓存文件,或将缓存内容减少到指定大小以下。 如果下游存储太大,这可能很有用。 有关详细信息,请参阅 AgeStore