#.net #clr #jit #disassembly
#.net #clr #jit #дизассемблирование
Вопрос:
По той или иной причине я иногда нахожу полезным или просто интересным посмотреть на оптимизированный вывод компилятора для функции.
Для неуправляемого кода на C / C моим любимым способом сделать это была компиляция в режиме выпуска, установка точки останова в интересующей функции, запуск и просмотр дизассемблирования в Visual Studio при достижении точки останова.
Недавно я попробовал это с проектом C # и обнаружил, что этот метод не работает. Даже в режиме выпуска дизассемблирование, которое я вижу, явно не оптимизировано. Я нашел и отключил (в Visual Studio 2010) «Debug … Опции и настройки … Отладка … Общая информация… Опция «Подавить JIT-оптимизацию при загрузке модуля», которая предположительно приближает меня к тому, что я хочу, только теперь она предупреждает меня, когда я пытаюсь ее запустить, и тогда я не могу заставить ее остановиться на точке останова, чтобы я мог видеть дизассемблирование.
Итак, если я хочу увидеть дизассемблированный, оптимизированный вывод дрожания CLR (4.0) для функции, каков наилучший способ сделать это? Чтобы внести ясность, я хотел бы увидеть дизассемблирование x86 (или, предпочтительно, x86_64), а не только дизассемблирование IL (которое вы можете увидеть в Reflector).
Ответ №1:
Конечно, после половины дня поиска ответа на этот вопрос я сам нахожу ответ через 5 минут после того, как задаю вопрос на SO.
Я был близок к этому; единственным недостающим шагом из того, что у меня было в вопросе, было то, что «Включить только мой код» также должно быть снято в параметрах.
Полное руководство доступно здесь: http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx
Комментарии:
1. Разве вам не нравится (и не ненавистно), когда это происходит? 🙂
2. @leppie: В значительной степени. Это был случай, когда нужно было знать решение, чтобы знать, по какой фразе искать решение…
3. ссылка недоступна
Ответ №2:
Я полагаю, что JIT знает, когда вы работаете под управлением отладчика, и генерирует более «удобный для отладчика» код x86, который объясняет, почему код x86, который вы видели, был неоптимизированным.
Вы могли бы попробовать запустить приложение автономно, выполнив интересующий вас код хотя бы один раз (чтобы он выполнялся JITting без подключенного отладчика), затем подключить отладчик к процессу и установить точку останова.
Ответ №3:
Точки останова в оптимизированном коде не работают во встроенных функциях. Если вы хотите просмотреть дизассемблирование встроенной функции, вы можете вставить command System.Diagnostics.Debugger.Break();
в свой исходный код.
Ответ №4:
Вы могли бы попробовать проверить сборку NGEN’d, но это было бы довольно сложно, поскольку отсутствуют метаданные. Но это могло бы сработать 🙂
Ответ №5:
Запуск под управлением VisualStudio независимо от того, находитесь ли вы в режиме отладки или выпуска, все равно будет выполняться под управлением отладчика. Поскольку он выполняется под управлением отладчика, он не может работать с оптимизированным кодом.
Комментарии:
1. Это правда? Если да, то почему вы можете подключить отладчик к процессу, который был запущен независимо от отладчика? Не забывайте, что VS тоже может отлаживать собственные приложения, но вы видите только дизассемблирование (инструкции по сборке) вместо C # или IL, и вы видите регистры вместо локальных. Я не уверен, сможете ли вы загрузить SOS.dll для дальнейшего изучения памяти, если вы подключаетесь к процессу, который не был запущен с помощью отладчика. Также обратите внимание, что они изменили некоторые элементы в собственных API отладки / инструментирования с помощью .NET 4, iirc.