【问题标题】:WinDbg cannot resolve .NET Core libraries symbolsWinDbg 无法解析 .NET Core 库符号
【发布时间】:2022-02-23 13:48:31
【问题描述】:

我是 WinDbg 的新手,最近开始使用它来查看由 JIT 编译器为 C# 代码生成的 JIT 汇编代码。 (我知道还有其他方法,例如Sharplab.io,但仍然)

以下是我使用 .NET 6 构建的简单程序。我想查看 PrintNumber 方法的 JITed 代码。

using System.Runtime.CompilerServices;

public class Program
{
    public static void Main()
    {
        PrintNumber();
        Console.ReadLine();
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    public static void PrintNumber()
    {
        int number = 5;
        Console.WriteLine("The number is " + number);
    }
}

当我在 Visual Studio 内置反汇编程序中看到上述代码时,我看到以下汇编代码。正如您所看到的(我用红色边框突出显示了它)Visual Studio 可以正确地将调用指令地址解析为将被调用的正确 .NET 方法名称。

但是如果我在 WinDbg 中打开相同的方法汇编代码,我会看到以下汇编代码。正如我所强调的,WinDbg 无法将调用指令解析为实际的 .NET 方法名称,而只是显示地址。

似乎是符号问题,但找不到解决方案。 我在 WinDbg 下有以下符号的设置

【问题讨论】:

  • 你是用SOS扩展和!u命令反汇编吗?
  • 是的,我通过.loadby sos coreclr 加载了SOS,但仍然无效。不,我不使用!u 命令进行反汇编。我启动可执行文件并运行到最后我执行!name2ee Sample!Program.PrintNumber 命令来查找该方法的 JIT ASM 代码。

标签: c# assembly windbg jit


【解决方案1】:

它似乎在这里工作

0:000> !Name2EE pnum Program.PrintNumber
Module:      00007ff81d374148
Assembly:    pnum.exe
Token:       0000000006000002
MethodDesc:  00007ff81d375a10
Name:        Program.PrintNumber()
JITTED Code Address: 00007ff81d4808e0
0:000> !U /d 00007ff81d4808e0
Normal JIT generated code
Program.PrintNumber()
Begin 00007ff81d4808e0, size 72

C:\Users\xxx\Desktop\pnum\pnum.cs @ 14:
>>> 00007ff8`1d4808e0 55              push    rbp
00007ff8`1d4808e1 57              push    rdi
00007ff8`1d4808e2 4883ec38        sub     rsp,38h
00007ff8`1d4808e6 488d6c2440      lea     rbp,[rsp+40h]
00007ff8`1d4808eb 488d7de0        lea     rdi,[rbp-20h]
00007ff8`1d4808ef b906000000      mov     ecx,6
00007ff8`1d4808f4 33c0            xor     eax,eax
00007ff8`1d4808f6 f3ab            rep stos dword ptr [rdi]
00007ff8`1d4808f8 833dc93cefff00  cmp     dword ptr [00007ff8`1d3745c8],0
00007ff8`1d4808ff 7405            je      00007ff8`1d480906
00007ff8`1d480901 e8cabfa25f      call    clr!JIT_DbgIsJustMyCode (00007ff8`7ceac8d0)
00007ff8`1d480906 90              nop

C:\Users\xxx\Desktop\pnum\pnum.cs @ 15:
00007ff8`1d480907 c745f405000000  mov     dword ptr [rbp-0Ch],5

C:\Users\xxx\Desktop\pnum\pnum.cs @ 16:
00007ff8`1d48090e 48b9a085e778f87f0000 mov rcx,offset mscorlib_ni!System.Reflection.RuntimeMethodInfo.get_IsOverloaded()$##600464C <PERF> (mscorlib_ni+0x285a0) (00007ff8`78e785a0)
00007ff8`1d480918 e8131c525f      call    clr!JIT_TrialAllocSFastMP_InlineGetThread (00007ff8`7c9a2530)
00007ff8`1d48091d 488945e8        mov     qword ptr [rbp-18h],rax
00007ff8`1d480921 488b55e8        mov     rdx,qword ptr [rbp-18h]
00007ff8`1d480925 8b4df4          mov     ecx,dword ptr [rbp-0Ch]
00007ff8`1d480928 894a08          mov     dword ptr [rdx+8],ecx
00007ff8`1d48092b 488b55e8        mov     rdx,qword ptr [rbp-18h]
00007ff8`1d48092f 488b0c258036e312 mov     rcx,qword ptr [12E33680h] ("The number is ")
00007ff8`1d480937 e8e4baf55b      call    mscorlib_ni!System.String.Concat(System.Object, System.Object)$##6000550 (00007ff8`793dc420)
00007ff8`1d48093c 488945e0        mov     qword ptr [rbp-20h],rax
00007ff8`1d480940 488b4de0        mov     rcx,qword ptr [rbp-20h]
00007ff8`1d480944 e8570df35b      call    mscorlib_ni!System.Console.WriteLine(System.String)$##6000B79 (00007ff8`793b16a0)
00007ff8`1d480949 90              nop

C:\Users\xxx\Desktop\pnum\pnum.cs @ 17:
00007ff8`1d48094a 90              nop
00007ff8`1d48094b 488d65f8        lea     rsp,[rbp-8]
00007ff8`1d48094f 5f              pop     rdi
00007ff8`1d480950 5d              pop     rbp
00007ff8`1d480951 c3              ret

调用栈

0:000> !DumpStack
OS Thread Id: 0x263c (0)
Current frame: (MethodDesc 00007ff81d375a10 +0x26 Program.PrintNumber())
Child-SP         RetAddr          Caller, Callee
0000000000b4ed00 00007ff81d4808b4 (MethodDesc 00007ff81d375a00 +0x24 Program.Main()), calling 00007ff81d480488 (stub for Program.PrintNumber())
0000000000b4ed08 00007ff87c9a7070 clr!MethodDescCallSite::CallTargetWorker+0x8e, calling clr!_chkstk
0000000000b4ed40 00007ff87c9a6923 clr!CallDescrWorkerInternal+0x83
0000000000b4ed48 00007ff87c9a7070 clr!MethodDescCallSite::CallTargetWorker+0x8e, calling clr!_chkstk
0000000000b4ed80 00007ff87c9a6838 clr!CallDescrWorkerWithHandler+0x4e, calling clr!CallDescrWorkerInternal
0000000000b4ed90 00007ff87c9a73cc clr!ArgIteratorTemplate<ArgIteratorBase>::GetNextOffset+0x2c, calling clr!ArgIteratorTemplate<ArgIteratorBase>::HasRetBuffArg
0000000000b4edc0 00007ff87c9a70e8 clr!MethodDescCallSite::CallTargetWorker+0x102, calling clr!CallDescrWorkerWithHandler
0000000000b4ee10 00007ff87cb3c851 clr!MethodDesc::IsVoid+0x21, calling clr!MetaSig::IsReturnTypeVoid
0000000000b4ee30 00007ff87c9a7070 clr!MethodDescCallSite::CallTargetWorker+0x8e, calling clr!_chkstk
0000000000b4eec0 00007ff87cb3b210 clr!RunMain+0x25f, calling clr!MethodDescCallSite::CallTargetWorker
0000000000b4f060 00007ff87caa8e4f clr!Thread::SetBackground+0x9e, calling clr!ThreadSuspend::UnlockThreadStore
0000000000b4f0a0 00007ff87cb3bab7 clr!Assembly::ExecuteMainMethod+0xb7, calling clr!RunMain
0000000000b4f130 00007ff88e5fb44d ntdll!RtlpAllocateHeapInternal+0xa2d, calling ntdll!RtlpAllocateHeap
0000000000b4f1e0 00007ff88e5f5ba1 ntdll!RtlpFreeHeapInternal+0x491, calling ntdll!RtlpHpStackLoggingEnabled
0000000000b4f210 00007ff88c171a5e KERNELBASE!WaitForSingleObjectEx+0x8e, calling ntdll!NtWaitForSingleObject
0000000000b4f240 00007ff87cb03ade clr!AppDomain::GetFriendlyNameForDebugger+0x98, calling clr!SString::GetUnicode
0000000000b4f2a0 00007ff88e5f47b1 ntdll!RtlFreeHeap+0x51, calling ntdll!RtlpFreeHeapInternal
0000000000b4f2e0 00007ff87c9a5829 clr!EEHeapFreeInProcessHeap+0x45, calling KERNEL32!HeapFreeStub
0000000000b4f320 00007ff87cb049cb clr!MulticoreJitManager::AutoStartProfile+0x38, calling clr!CLRConfig::GetConfigValue
0000000000b4f330 00007ff87ca50c3e clr!SBuffer::Set+0x46, calling clr!memcpy
0000000000b4f350 00007ff87cb3c73f clr!PEFileSecurityDescriptor::`vector deleting destructor'+0x2f, calling clr!operator delete
0000000000b4f390 00007ff87cb3b96b clr!SystemDomain::ExecuteMainMethod+0x643, calling clr!Assembly::ExecuteMainMethod
0000000000b4f3c0 00007ff87c9a600d clr!EEConfig::GetConfiguration_DontUse_+0x36, calling clr!GetThread
0000000000b4f580 00007ff87c9c8a5c clr!Alloc+0x1af
0000000000b4f5d0 00007ff87c9aaec9 clr!HndAssignHandle+0x25, calling clr!HndWriteBarrier
0000000000b4f600 00007ff87caa8d64 clr!HndCreateHandle+0x8c, calling clr!StressLog::LogOn
0000000000b4f610 00007ff87caa9799 clr!GCHandleManager::CreateGlobalHandleOfType+0x39
0000000000b4f640 00007ff87caa9dd6 clr!CreateGlobalHandleCommon+0x4e, calling clr!DiagHandleCreated
0000000000b4f670 00007ff87cb08a35 clr!AppDomain::SetupSharedStatics+0xf5, calling clr!ErectWriteBarrier
0000000000b4f690 00007ff87cb2d129 clr!SafeHandle::Init+0x41, calling clr!MethodDesc::GetSlot
0000000000b4f6c0 00007ff87cb335b2 clr!EEStartupHelper+0x822, calling clr!CLRException::HandlerState::CleanupTry
0000000000b4f730 00007ff88e5f5ba1 ntdll!RtlpFreeHeapInternal+0x491, calling ntdll!RtlpHpStackLoggingEnabled
0000000000b4f930 00007ff87cb32d65 clr!EEStartup+0x15, calling clr!EEStartupHelper
0000000000b4f990 00007ff87cb3b2b4 clr!ExecuteEXE+0x3f, calling clr!SystemDomain::ExecuteMainMethod
0000000000b4fa00 00007ff87cb3b00d clr!_CorExeMainInternal+0xb2, calling clr!ExecuteEXE
0000000000b4fa60 00007ff88e6207b0 ntdll!RtlSetLastWin32Error+0x40, calling ntdll!_security_check_cookie
0000000000b4fa90 00007ff87cb3c1f4 clr!CorExeMain+0x14, calling clr!_CorExeMainInternal
0000000000b4fad0 00007ff87d6e8c01 mscoreei!CorExeMain+0x112
0000000000b4fb00 00007ff881741560 MSCOREE!GetShimImpl+0x18, calling MSCOREE!InitShimImpl
0000000000b4fb10 00007ff88174acd2 MSCOREE!CorExeMain_Exported+0x102, calling KERNEL32!GetProcAddressStub
0000000000b4fb30 00007ff88174ac42 MSCOREE!CorExeMain_Exported+0x72, calling MSCOREE!guard_dispatch_icall_nop
0000000000b4fb60 00007ff88d6f7034 KERNEL32!BaseThreadInitThunk+0x14, calling KERNEL32!guard_dispatch_icall_nop
0000000000b4fb90 00007ff88e622651 ntdll!RtlUserThreadStart+0x21, calling ntdll!guard_dispatch_icall_nop

【讨论】:

  • 您希望我执行任何故障排除步骤!?我准备好了!
  • 我安装了这个版本 Debugger client version: 1.2111.9001.0 and Debugger engine version: 10.0.22473.1005
  • 我没有做任何特别的事情,您的代码缺少 using System: 添加它按原样使用 csc -debug blah.cs 编译,因为 x64 在 windbg 中打开它时添加了一个 sxe ld:clr when clr was loaded used 。加载 sos ;!sosflush;!name2ee blah foo.bar 这就是我在 winx 上使用旧版 windbg
  • 我也试过了,但还是不行。顺便说一句,我正在使用 WinDBG 预览,可以在此处获得 microsoft.com/en-us/p/windbg-preview/… 我什至检查了符号文件,system.console.pdb 在那里,但是,不知何故,我没有得到方法名称,而是显示调用指令。您可以尝试使用 Windbg 预览版吗?这样我们就可以弄清楚是版本问题还是什么!
  • 输出来自 .NET Framework 内存转储。我有与@ShreyasJejurkar 相同的问题,带有.NET 6 内存转储。这只是一个理论,但我怀疑在引入分层 JIT 时,SOS 并未更新以了解如何导航新的存根。
【解决方案2】:

是的,正如 Kevin Gosse 所说,我猜 SOS 无法在 TiredCompilation 开启时找到符号。我们需要通过将环境变量 COMPlus_TieredCompilation 设置为 0 来禁用它(可能只在开发机器上这样做)。 我试过了,然后 WinDbg(更具体地说是 SOS)能够正确加载符号文件,并且能够解析方法调用地址。

遗憾的是,这在任何地方都没有得到很好的记录。像这样的问题会严重破坏新人的积极性。

更多信息 => https://twitter.com/ShreyasJejurkar/status/1496160952479551492

感谢 Kevin Gosse 的大力帮助!

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 2010-10-03
    • 2020-08-09
    • 2019-05-22
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多