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
指定下游存储。 这是用于缓存单个符号文件的本地目录或网络共享。

可以指定多个下游存储,可以通过星号分隔它们。 页面稍后在级联下游存储中解释了多个下游存储。

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

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

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

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

\\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 来缓存从微软公共符号存储库中获取的符号,因为符号服务器 (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

SymSrv 如何查找文件

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

将在生成的目录中搜索符号文件或符号存储指针文件。

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

使用 AgeStore 减小缓存大小

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