【问题标题】:How to dump .NET JIT-ed generic method with windbg?如何使用windbg转储.NET JIT-ed泛型方法?
【发布时间】:2018-11-13 12:35:32
【问题描述】:

我需要检查 JIT 为具有不同结构参数的通用方法发出的代码。我阅读了有关 WinDbg 和 SOS.dll 的文章,并且可以检查非泛型方法。但是对于泛型方法,应该为每个结构类型进行 JIT 编辑,方法表中没有 JIT 编辑代码,我在哪里可以找到它?

namespace ConsoleApp1
{
    class Program
    {
        public void Foo<T>(T arg)
        {
            //some code here
        }

        static void Main(string[] args)
        {
            var program = new Program();
            program.Foo("test");
            program.Foo(1.0);
            program.Foo(new Guid());
            program.Foo((byte)1);
            program.Foo((char)1);
            program.Foo(1);
        }
    }
}

WinDbg:

0:006> .loadby sos clr
0:006> !Name2EE ConsoleApp1!ConsoleApp1.Program
Module:      00007ffa3abf4118
Assembly:    ConsoleApp1.exe
Token:       0000000002000002
MethodTable: 00007ffa3abf5a18
EEClass:     00007ffa3abf24b8
Name:        ConsoleApp1.Program

转储方法表

0:006> !DumpMT -md 00007ffa3abf5a18
    EEClass:         00007ffa3abf24b8
    Module:          00007ffa3abf4118
    Name:            ConsoleApp1.Program
    mdToken:         0000000002000002
    File:            D:\repos\ConsoleApp1\ConsoleApp1\bin\Debug\net462\ConsoleApp1.exe
    BaseSize:        0x18
    ComponentSize:   0x0
    Slots in VTable: 7
    Number of IFaces in IFaceMap: 0
    --------------------------------------
    MethodDesc Table
               Entry       MethodDesc    JIT Name
    00007ffa9759c080 00007ffa970f7fb8 PreJIT System.Object.ToString()
    00007ffa97604360 00007ffa970f7fc0 PreJIT System.Object.Equals(System.Object)
    00007ffa97674770 00007ffa970f7fe8 PreJIT System.Object.GetHashCode()
    00007ffa975cf570 00007ffa970f8000 PreJIT System.Object.Finalize()
    00007ffa3ad005c0 00007ffa3abf5a10    JIT ConsoleApp1.Program..ctor()
    00007ffa3ad00078 00007ffa3abf59e0   NONE ConsoleApp1.Program.Foo(!!0) // "base" IL code
    00007ffa3ad00480 00007ffa3abf5a00    JIT ConsoleApp1.Program.Main(System.String[])

而且我没有 Foo 的代码

0:006> !U 00007ffa3abf59e0
Not jitted yet

有什么想法吗?

【问题讨论】:

  • 看看this page是否能帮到你。 (我懒得自己尝试并编造答案。)
  • 如果您只想检查各种 C# 的 IL 结果,请转到sharplab.io;我在那里输入了你的代码,它确实显示了Foo的IL
  • @JeroenMostert,我已经看到了,没有什么可以帮助我
  • @sellotape,很酷的项目!但我不需要 IL 代码,因为泛型方法的 IL 代码与类型无关,我需要 JIT 代码。但是我通过属性 [SharpLab.Runtime.JitGeneric(typeof(int))] 并选择 JIT asm 得到了想要的结果,谢谢!
  • @HansPassant,不,我确定此时代码是 jited 的。问题是jited泛型方法没有存储在这个表中,MT只有所有类型通用的IL代码,“开放泛型”。

标签: c# .net generics windbg


【解决方案1】:

我获取了您的代码并将其编译为 x86 调试版本。然后我附加到该进程并等待它终止。

我发现和你一样的结果:

   Entry MethodDe    JIT Name
[...]
00250038 00204d34   NONE JitExample2.Program.Foo(!!0)

这里写着NONE,意思是“不跳动”。

0:000> !dumpmd  00204d34  
Method Name:  JitExample2.Program.Foo(!!0)
[...]
IsJitted:     no

所以答案似乎得到了证实:它没有被jitted。

我不知道获取 jitted 泛型方法列表的任何官方方法。但在!bpmd 的帮助下,这是可能的:

0:000> !bpmd JitExample2 JitExample2.Program.Foo
Found 1 methods in module 00204024...
MethodDesc = 00204d34
Setting breakpoint: bp 0025074A [JitExample2.Program.Foo[[System.Char, mscorlib]](Char)]
Setting breakpoint: bp 002506EA [JitExample2.Program.Foo[[System.Byte, mscorlib]](Byte)]
Setting breakpoint: bp 00250687 [JitExample2.Program.Foo[[System.Guid, mscorlib]](System.Guid)]
Setting breakpoint: bp 00250627 [JitExample2.Program.Foo[[System.Double, mscorlib]](Double)]
Setting breakpoint: bp 002505B0 [JitExample2.Program.Foo[[System.__Canon, mscorlib]](System.__Canon)]
Setting breakpoint: bp 002507AA [JitExample2.Program.Foo[[System.Int32, mscorlib]](Int32)]

然后您可以使用bp 之后的地址来显示 JIT 代码:

0:000> !u 0025074A 
Normal JIT generated code
JitExample2.Program.Foo[[System.Char, mscorlib]](Char)
Begin 00250728, size 4b

C:\Users\For example John\JitExample2\Program.cs @ 8:
00250728 55              push    ebp
00250729 8bec            mov     ebp,esp
0025072b 83ec10          sub     esp,10h
0025072e 33c0            xor     eax,eax
[...]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 2020-03-14
    • 2019-08-17
    • 1970-01-01
    相关资源
    最近更新 更多