Получить вывод JIT - PullRequest
       32

Получить вывод JIT

10 голосов
/ 03 августа 2011

Мне интересно посмотреть фактический вывод сборки x86 программой C # (а не инструкциями байт-кода CLR).Есть ли хороший способ сделать это?

Ответы [ 5 ]

8 голосов
/ 03 августа 2011

Во время отладки приложения в Visual Studio вы можете щелкнуть правой кнопкой мыши код, который вы остановили (с помощью точки останова), и нажать «Перейти к разборке».Вы можете отлаживать с помощью встроенных инструкций.

Что касается этого с файлами * .exe на диске, возможно, вы могли бы использовать NGen для генерации собственного вывода, а затем разбирать его (хотя я никогда не пробовал этого, поэтому я не могу гарантировать, что это сработает).

Вот несколько примеров кодов операций из простой арифметической операции, написанной на c #:

            int x = 5;
mov         dword ptr [ebp-40h],5 
            int y = 6;
mov         dword ptr [ebp-44h],6 
            int z = x + y;
mov         eax,dword ptr [ebp-40h] 
add         eax,dword ptr [ebp-44h] 
mov         dword ptr [ebp-48h],eax 
5 голосов
/ 25 апреля 2015

Когда @IvanDanilov ответил , вы можете использовать WinDbg и SOS.Я отвечаю отдельно, чтобы обеспечить пошаговое руководство.

В этом примере я хочу просмотреть разборку метода AreEqual () из:

using System;

namespace TestArrayCompare
{
    class Program
    {
        static bool AreEqual(byte[] a1, byte[] a2)
        {
            bool result = true;
            for (int i = 0; i < a1.Length; ++i)
            {
                if (a1[i] != a2[i])
                    result = false;
            }
            return result;
        }

        static void Main(string[] args)
        {
            byte[] a1 = new byte[100];
            byte[] a2 = new byte[100];
            if (AreEqual(a1, a2))
            {
                Console.WriteLine("`a1' equals `a2'.");
            }
            else
            {
                Console.WriteLine("`a1' does not equal `a2'.");
            }
        }
    }
}

Шаги:

  1. Открыть WinDbg.В меню «Файл» выберите «Открыть исполняемый файл ...».Найдите расположение EXE (в моем случае, C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release\TestArrayCompare.exe).
  2. Добавьте каталог, содержащий файл PDB, к пути символа.Например:

    .sympath "C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release"
    
  3. В окне команд WinDbg установите точку останова при загрузке clr.dll через:

    sxe ld:clr
    
  4. Продолжитьзапустив команду 'Go': g

  5. В ModLoad clr.dll загрузите SOS: .loadby sos clr
  6. Запустите BPMD для прерывания метода длякоторый вы хотите увидеть разборки.Например:

    0:000> !BPMD TestArrayCompare.exe TestArrayCompare.Program.AreEqual
    Adding pending breakpoints...
    
  7. Продолжите снова, введя команду 'Go': g

  8. Запустите Name2EE, чтобы увидеть дескриптор метода,Например:

    0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual
    Module:      00a62edc
    Assembly:    TestArrayCompare.exe
    Token:       06000001
    MethodDesc:  00a637a4
    Name:        TestArrayCompare.Program.AreEqual(Byte[], Byte[])
    Not JITTED yet. Use !bpmd -md 00a637a4 to break on run.
    
  9. Запустите команду BPMD в строке «Пока не выполнено».Например:

    0:000> !bpmd -md 00a637a4
    MethodDesc = 00a637a4
    Adding pending breakpoints...
    
  10. Продолжите снова: g

  11. Вы должны увидеть «JITTED ...» в окне команд.Повторите команду Name2EE, чтобы увидеть адрес кода JIT.Например:

    0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual
    Module:      00a62edc
    Assembly:    TestArrayCompare.exe
    Token:       06000001
    MethodDesc:  00a637a4
    Name:        TestArrayCompare.Program.AreEqual(Byte[], Byte[])
    JITTED Code Address: 00b500c8
    
  12. Используйте команду u для дизассемблирования, начиная с указанного кодового адреса.Например:

    0:000> u 00b500c8 L20
    00b500c8 55              push    ebp
    00b500c9 8bec            mov     ebp,esp
    00b500cb 57              push    edi
    00b500cc 56              push    esi
    ...
    

(Для вышеизложенного я использовал WinDbg 6.3.9600.17200 X86 из Windows 8.1 SDK.)

Один удобный справочник - Справочная страница SOS.dll (SOS Debugging Extension) на MSDN .

5 голосов
/ 03 августа 2011

Вам следует использовать WinDbg с SOS / SOSEX, убедиться, что метод, для которого вы хотите увидеть код x86, JITted в таблицах методов, а затем увидеть фактическую разборку с помощью команды u.Таким образом, вы увидите реальный код.

Как уже упоминалось здесь, с помощью ngen вы можете увидеть код, который не совсем соответствует фактическому результату JIT-компиляции.В Visual Studio это также возможно, поскольку компиляция JIT сильно зависит от того, присутствует ли отладчик или нет.

UPD: некоторые пояснения.WinDbg также является отладчиком, но он нативный один.

Здесь вы можете прочитать о технике подробно.

2 голосов
/ 03 августа 2011

Вы можете использовать Visual Studio Debugger, установив точку останова и затем просмотрев окно «Разборка» ( Alt + Ctrl + D ) или попробовать Native Image Generator Tool (ngen.exe) .

1 голос
/ 03 августа 2011

Вы можете сделать дамп памяти.Однако обратите внимание, что код в памяти не обязательно содержит каждый метод.

ngen выполняет AOT или генерацию кода с опережением времени, который может отличаться от кода JIT.

...