WinDbg 加载符号需要很长时间;正在搜索大型网络 UNC 符号存储中的每个目录

WinDbg takes extremely long time to loading symbols; is searching every directory in large network UNC symbol store

在使用 WinDbg 调试崩溃转储时,我花了好几天时间尝试加快符号的加载速度,但我无法解决一个特定的问题。

问题是,当转储中模块的符号不存在于任何可访问的符号存储或符号服务器位置时(例如,它是 third-party 没有可用符号的模块),WinDbg 将花费数小时寻找他们。

我已正确设置我的符号路径以正确设置搜索顺序和缓存目录:

.sympath cache*C:\SymbolCache1;\our.corp\SymbolStore;SRV*C:\SymbolCache2*http://msdl.microsoft.com/download/symbols

运行 !sym noisy.reload /f 我可以看到:

SYMSRV:  Notifies the client application that a proxy has been detected. 
SYMSRV:  Connecting to the Server: http://msdl.microsoft.com/download/symbols. 
SYMSRV:  Successfully connected to the Server. 
SYMSRV:  Sending the information request to the server. 
SYMSRV:  Successfully sent the information request to the server. 
SYMSRV:  Waiting for the server to respond to a request. 
SYMSRV:  Successfully received a response from the server. 
SYMSRV:  Closing the connection to the Server. 
SYMSRV:  Successfully closed the connection to the Server. 
SYMSRV:  c:\SymbolCache1\Some3rdParty.dll[=11=]60D200cd1000\Some3rdParty.dll not found 
SYMSRV:  c:\SymbolCache2\Some3rdParty.dll[=11=]60D200cd1000\Some3rdParty.dll not found 
SYMSRV:  http://msdl.microsoft.com/download/symbols/Some3rdParty.dll/0060D200cd1000/Some3rdParty.dll not found 
<---- !!!! hanging here with *BUSY* showing in WinDbg

通过 运行 Process Monitor 在它挂起的地方,我可以看到 WinDbg 正在搜索似乎是 每个目录 在我们巨大的网络符号库 (\our.corp\SymbolStore) 中查找符号,即使在明显不相关的模块目录中也是如此。

奇怪的是,在 WinDbg 中,您可以看到它提取了模块的时间戳 (0060D200cd1000),并使用它来查看本地目录和 MS 符号服务器中的预期位置。我不明白为什么它要对我们的(大量)网络符号存储进行全面扫描。也许它处理 UNC 路径的方式有一些独特之处?

此搜索每个符号可能需要 15 分钟或更长时间,如果转储有许多缺失的符号,这可能会导致 !analyze -v 花费数小时(如果您使用 Visual Studio 集成WinDbg,一旦加载故障转储,它就会导致挂起,因为出于某种原因,集成会尝试立即加载所有符号,尽管 .symopt 设置)。

如果您尝试加载 non-existent made-up 模块名称的符号,这个问题也很容易重现,例如.reload /f bogus.dll

这是我的 WinDbg .symopt 设置:

0:000> .symopt
Symbol options are 0x30337:
  0x00000001 - SYMOPT_CASE_INSENSITIVE
  0x00000002 - SYMOPT_UNDNAME
  0x00000004 - SYMOPT_DEFERRED_LOADS
  0x00000010 - SYMOPT_LOAD_LINES
  0x00000020 - SYMOPT_OMAP_FIND_NEAREST
  0x00000100 - SYMOPT_NO_UNQUALIFIED_LOADS
  0x00000200 - SYMOPT_FAIL_CRITICAL_ERRORS
  0x00010000 - SYMOPT_AUTO_PUBLICS
  0x00020000 - SYMOPT_NO_IMAGE_SEARCH

我找遍了想一定有一些标志来控制它,但我似乎找不到它。

几件事:

我终于找到了一个不尽如人意但非常好的解决方案:设置一个SymProxy

这让我可以从我的符号路径中删除 UNC 共享,并将其替换为对 SymProxy 的引用作为我的 http 符号服务器。

.sympath SRV*C:\SymbolCache*http://somemachine.our.corp/Symbols

代理本身仍然在 UNC 共享中搜索,但 WinDbg 不能再搜索网络目录——相反,它必须将有关它想要的符号的信息传递给 SymProxy,而 SymProxy 只在一个位置查找UNC 共享而不是进行详尽搜索。

这并不能解释为什么 WinDbg 会搜索整个 UNC 共享,但它确实解决了 WinDbg 在搜索符号时挂起的问题。符号加载终于又快了!

安装 SymProxy 的另一个优点是您可以将其设置为从多个符号位置提取。例如,您可以将其连接到本地组织的符号存储以及 Microsoft 符号服务器。然后您的开发人员可以将他们的符号路径设置为仅引用 SymProxy 而不是多个符号位置。

不应该是:

.sympath cache*C:\SymbolCache1;SRV*\our.corp\SymbolStore;SRV*C:\SymbolCache2*http://msdl.microsoft.com/download/symbols  

也就是说,通过在没有 SRV* 的情况下列出 \our.corp\SymbolStore,您告诉 dbghelp 在这个非结构化目录中查找符号。如果您使用 SRV* 语法,那么您就是在告诉 dbghelp 让 symsrv 以非常具体和结构化的方式查看该目录。

symsrv.dll 可以有效地搜索 Microsoft 的符号服务器,它也可以有效地搜索你的,如果你告诉它用 SRV* 这样做的话。