Как сбросить .NET JIT-ed универсальный метод с помощью windbg? - PullRequest
0 голосов
/ 13 ноября 2018

Мне нужно проверить код, который JIT генерирует для универсального метода с различными параметрами структуры. Я читаю статьи о WinDbg и SOS.dll , и можно проверить неуниверсальные методы. Но для универсальных методов, которые должны быть JIT-ed для каждого типа структуры, в таблице методов нет JIT-ed кода, где я могу его найти?

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

Есть ли идеи?

1 Ответ

0 голосов
/ 14 ноября 2018

Я взял ваш код и скомпилировал его как отладочную сборку 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

Таким образом, ответ, кажется, подтвержден: он не связан.

Я не знаю ни одного официального метода получения списка сопряженных обобщенных методов.Но с помощью !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
[...]
...