未加载 ngen-ed 程序集的符号

Posted

技术标签:

【中文标题】未加载 ngen-ed 程序集的符号【英文标题】:Symbols for ngen-ed assemblies are not loaded 【发布时间】:2017-03-24 06:16:56 【问题描述】:

我正在尝试从 procmon 解码以下调用堆栈行:

29  System.Management.Automation.ni.dll System.Management.Automation.ni.dll + 0x897a0a  0x7fee2ae7a0a   C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Manaa57fc8cc#\a86698074f28597f1fc5ceabfed6fed6\System.Management.Automation.ni.dll

如您所见,其中有一个 NGEN 版本的程序集:System.Management.Automation.ni.dll。我用 ngen createpdb 为它创建了一个 pdb 文件:

PS> ngen createpdb c:\Windows\assembly\NativeImages_v4.0.30319_64\System.Manaa57fc8cc#\a86698074f28597f1fc5ceabfed6fed6\System.Management.Automation.ni.dll c:\symbols\ngen

Successfully generated PDB for native assembly 'c:\Windows\assembly\NativeImages_v4.0.30319_64\System.Manaa57fc8cc#\a8698074f28597f1fc5ceabfed6fed6\System.Management.Automation.ni.dll'.
PDB generated in directory c:\symbols\ngen\System.Management.Automation.ni.pdb a86698074f28597f1fc5ceabfed6fed61\

我在 _NT_SYMBOL_PATH 变量中的符号路径是:

SRV*C:\symbols\ngen*;SRV*C:\symbols\dbg*http://referencesource.microsoft.com/symbols;SRV*C:\symbols\dbg*http://msdl.microsoft

.com/download/symbols

但是我仍然可以看到新生成的符号文件没有为程序集加载:

PS a86698074f28597f1fc5ceabfed6fed6> dbh -n .\System.Management.Automation.ni.dll
verbose mode on.
DBGHELP: No header for .\System.Management.Automation.ni.dll.  Searching for image on disk
DBGHELP: C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Manaa57fc8cc#\a86698074f28597f1fc5ceabfed6fed6\System.Management.Automation.ni.dll - OK
SYMSRV:  C:\symbols\ngen\System.Management.Automation.pdb\6B8B8F14D0564CB893B6E84B43CAE67B1\System.Management.Automation.pdb - file not found
SYMSRV:  C:\tools\diag\Debugging Tools for Windows\x64\sym\System.Management.Automation.pdb\6B8B8F14D0564CB893B6E84B43CAE67B1\System.Management.Automation.pdb - file not found
SYMSRV:  C:\symbols\ngen\System.Management.Automation.pdb\6B8B8F14D0564CB893B6E84B43CAE67B1\System.Management.Automation.pdb not found
SYMSRV:  C:\tools\diag\Debugging Tools for Windows\x64\sym\System.Management.Automation.pdb\6B8B8F14D0564CB893B6E84B43CAE67B1\System.Management.Automation.pdb not found
DBGHELP: System.Management.Automation.ni - public symbols
        C:\symbols\dbg\System.Management.Automation.pdb\6B8B8F14D0564CB893B6E84B43CAE67B1\System.Management.Automation.pdb

我检查了 .dll 文件中的调试头,它有两个条目:

PS> dumpbin /headers .\System.Management.Automation.ni.dll
...
  Debug Directories
        Time Type        Size      RVA  Pointer
    -------- ------- -------- -------- --------
    56BEFBC1 cv           11C 01F200A4  1F1E8A4    Format: RSDS, A8669807-4F28-597F-1FC5-CEABFED6FED6, 1, System.Management.Automation.ni.pdb
    56BEFBC1 cv            39 01F201C0  1F1E9C0    Format: RSDS, 6B8B8F14-D056-4CB8-93B6-E84B43CAE67B, 1, System.Management.Automation.pdb
...

A8669807-4F28-597F-1FC5-CEABFED6FED6 条目是第一个,但似乎 dbh(或实际上是 dbghelp)从未使用过它,它只是在寻找 6B8B8F14- D056-4CB8-93B6-E84B43CAE67B。我尝试将符号路径仅设置为 C:\symbols\ngen,但这没有帮助 - 仍然找不到符号文件。

我的 dbghelp 版本是:10.0.10240.16399

谁能指出我在这里做错了什么?

编辑 1:

似乎 dbh 详细输出与 procmon 显示的内容非常一致:

编辑 2(对汉斯的回答)

我的应用程序实际上是一个 Powershell 脚本。我在 Process Hacker 中列出了 powershell.exe 的 .NET 模块,发现它使用的是 System.Management.Automation.dll 3.0.0 版:

我假设原始程序集位于 GAC:c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll

显然是为 .NET 4.0 创建的:

PS temp> corflags c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  4.6.1055.0
Copyright (c) Microsoft Corporation.  All rights reserved.
Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x9
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 1

现在,我还在 NativeImages 文件夹中查找了任何其他 System.Management.Automation 程序集,但 .NET 4.0 64 位只有 1 个:

.aux 标头似乎也只提到了 3.0.0 版本。另请注意,.ni 文件在 Debug 标头中引用了两个 PDB 文件。其中之一就是我想要的。

编辑 3 (fuslogvw)

按照 Hans 的建议,我为原生图像启用了 Fusion 日志。下面是显示自动化程序集加载路径的 sn-p:

... Pre-bind state information ...
LOG: DisplayName = System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///C:/Windows/System32/WindowsPowershell/v1.0/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = powershell.exe
Calling assembly : Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
...
LOG: Start validating all the dependencies.
LOG: [Level 1]Start validating native image dependency mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating native image dependency System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: [Level 1]Start validating native image dependency System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency Microsoft.Management.Infrastructure.Native, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: [Level 1]Start validating IL dependency System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency System.ServiceModel.Internals, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: [Level 1]Start validating IL dependency System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: [Level 1]Start validating IL dependency System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: [Level 1]Start validating IL dependency SMDiagnostics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
Native image has correct version information.
LOG: Validation of dependencies succeeded.
LOG: Bind to native image succeeded.
Attempting to use native image C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Manaa57fc8cc#\a86698074f28597f1fc5ceabfed6fed6\System.Management.Automation.ni.dll.
Native image successfully used.

【问题讨论】:

【参考方案1】:

上面的答案是正确的 - 这是微软的一个已知问题。

根据您要完成的工作,您也许可以使用 SOS 中的命令作为解决方法。例如,!ip2md 命令将 IP 解析为方法名称。 https://docs.microsoft.com/en-us/dotnet/framework/tools/sos-dll-sos-debugging-extension

【讨论】:

这看起来像是对上述答案的评论。请等到您有足够的声誉后再发表评论。【参考方案2】:

不幸的是,我认为这是 dbghelp 或 ngen 中的错误。我创建了一个 Test.dll 程序集并对其进行了 ngen 编辑:

ngen install Test.dll

它降落在:

c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\7dece650b5d91e7ac799a78b3d1b7c59\Test.ni.dll

正如预期的那样。我还为它创建了符号:

ngen createpdb c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\7dece650b5d91e7ac799a78b3d1b7c59\Test.ni.dll c:\symbols\ngen

当我检查调试头时,我又得到了两个:

> dumpbin /headers c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\7dece650b5d91e
7ac799a78b3d1b7c59\Test.ni.dll
  Debug Directories
        Time Type        Size      RVA  Pointer
    -------- ------- -------- -------- --------
    5824BFEB cv           11C 00003D40     1F40    Format: RSDS, 7DECE650-B5D9-1E7A-C799-A78B3D1B7C59, 1, Test.ni.pdb
    5824BFEB cv           11C 00002E5C     205C    Format: RSDS, F32EB2CE-973C-438F-BB78-A24D9971C194, 1, C:\temp\Test.pdb

当我尝试为 Test.ni.dll 加载符号时,dbh 尝试加载带有 F32EB2CE-973C-438F-BB78-A24D9971C194 签名的 .pdb 文件(这是错误的)。然后我打开了一个 HEX 编辑器,并替换了 PE 文件中列出的调试目录的顺序(我通过时间戳找到了它们:)):

现在,dumpbin 以不同的顺序显示它们:

Time     Type        Size      RVA  Pointer
-------- ------- -------- -------- --------
5824BFEB cv           11C 00002E5C     205C    Format: RSDS, F32EB2CE-973C-438F-BB78-A24D9971C194, 1, C:\temp\Test.pdb
5824BFEB cv           11C 00003D40     1F40    Format: RSDS, 7DECE650-B5D9-1E7A-C799-A78B3D1B7C59, 1, Test.ni.pdb

dbh 开始正常工作:

> dbh -n -s:SRV*c:\symbols\ngen* c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\
7dece650b5d91e7ac799a78b3d1b7c59\Test.ni.dll
verbose mode on.
DBGHELP: Symbol Search Path: SRV*c:\symbols\ngen*
Symbol Search Path: SRV*c:\symbols\ngen*
DBGHELP: No header for c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\7dece650b5d91e7ac799a78b3d1b7c59\Test.ni.dll.  Searching for image on disk
DBGHELP: c:\Windows\assembly\NativeImages_v4.0.30319_64\Test\7dece650b5d91e7ac799a78b3d1b7c59\Test.ni.dll - OK
DBGHELP: Test.ni - public symbols & lines
        c:\symbols\ngen\Test.ni.pdb\7DECE650B5D91E7AC799A78B3D1B7C591\Test.ni.pdb
Test.ni [1000000]:

我创建了一个 issue on connect 并请您投票。

【讨论】:

您可以通过在粘贴的控制台文本上按 Ctrl+K 来改进格式,而不是使用 ```` 使用预览来查看它是否格式良好。这次是我为你做的。 不知道。谢谢! @lowleveldesign 将原始 PDB 中的 RVA 3e5c 转换为已修补 PDB 中的 2e5c 有什么特别的原因吗?只是一个错字? @IanKemp 只是一个错字 - 我更新了答案。感谢您发现这一点。

以上是关于未加载 ngen-ed 程序集的符号的主要内容,如果未能解决你的问题,请参考以下文章

封闭源程序集的“无法验证的代码未通过策略检查”

混合模式程序集未加载本机 C++ pdb 的符号

无法加载文件或程序集。找到的程序集的清单定义与程序集引用不匹配

自动加载dll,加载dll中程序集的信息。

Windows 通用应用程序:无法加载文件或程序集 - 找到的程序集的清单定义与程序集引用不匹配

ASP.NET 与用于 .NET 的 Delphi 2007。无法加载文件或程序集...定位的程序集的清单定义与程序集引用不匹配