Как я могу просмотреть дизассемблирование оптимизированного кода .NET, созданного с помощью джиттинга?

По той или иной причине я иногда нахожу полезным или просто интересным посмотреть на оптимизированный вывод компилятора для функции.

Для неуправляемого кода C/C++ мой любимый способ сделать это — скомпилировать в режиме Release, установить точку останова в интересующей функции, запустить и просмотреть дизассемблированный код в Visual Studio, когда он достигнет точки останова.

Недавно я попробовал это с проектом C# и обнаружил, что этот метод не работает. Даже в режиме Release разборка, которую я вижу, явно не оптимизирована. Я нашел и отключил (в Visual Studio 2010) параметр «Отладка... Параметры и настройки... Отладка... Общие... Подавить оптимизацию JIT при загрузке модуля», который, по-видимому, приближает меня к тому, что я хочу, только теперь он предупреждает меня, когда я пытаюсь запустить его, и тогда я не могу заставить его остановиться на точке останова, чтобы я мог видеть дизассемблирование.

Итак, если я хочу увидеть разобранный, оптимизированный вывод джиттера CLR (4.0) для функции, как лучше всего это сделать? Чтобы было ясно, я хотел бы увидеть дизассемблирование x86 (или предпочтительно x86_64), а не только дизассемблирование IL (которое вы можете увидеть в Reflector).


person Wesley Hill    schedule 06.08.2010    source источник


Ответы (5)


Конечно, после полдня поиска ответа на этом, я сам нахожу ответ через 5 минут после того, как спрошу на ТАК.

Я был близко; единственный недостающий шаг из того, что у меня было в вопросе, заключался в том, что в параметрах также должен быть снят флажок «Включить только мой код».

Полное руководство доступно здесь: http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx

person Wesley Hill    schedule 06.08.2010
comment
Разве вы не любите (и ненавидите), когда это происходит? :) - person leppie; 06.08.2010
comment
@leppie: Довольно много. Это был тот случай, когда нужно было знать решение, чтобы знать, какую фразу искать, чтобы найти решение... - person Wesley Hill; 06.08.2010

Я считаю, что JIT знает, когда вы работаете под отладчиком, и генерирует более «дружественный для отладчика» код x86, что объясняет, почему код x86, который вы видели, был неоптимизирован.

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

person Joe White    schedule 06.08.2010

Точки останова в оптимизированном коде не работают во встроенных функциях. Если вы хотите просмотреть дизассемблирование встроенной функции, вы можете вставить команду System.Diagnostics.Debugger.Break(); в свой исходный код.

person palota    schedule 23.05.2017

Вы можете попробовать проверить сборку NGEN, но это будет довольно сложно, так как метаданные отсутствуют. Но это может сработать :)

person leppie    schedule 06.08.2010

Запуск в VisualStudio, независимо от того, находитесь ли вы в режиме отладки или в режиме выпуска, все равно будет выполняться под отладчиком. Поскольку он работает под отладчиком, он не может работать с оптимизированным кодом.

person Dave Black    schedule 01.03.2011
comment
Это правда? Если да, то почему вы можете присоединить отладчик к процессу, который был запущен независимо от отладчика? Не забывайте, что VS также может отлаживать нативные приложения, но вы видите только дизассемблирование (инструкции по сборке) вместо C# или IL, и вы видите регистры вместо локальных. Я не уверен, что вы можете загрузить SOS.dll, чтобы углубиться в память, если вы подключитесь к процессу, который не был запущен с помощью отладчика. Также обратите внимание, что они изменили некоторые вещи, связанные с собственными API-интерфейсами отладки/инструментирования с .NET 4, iirc. - person Drew Noakes; 02.03.2011