Создание исходного кода из сборок .NET во время отладки

При отладке приложения .NET может потребоваться просмотреть исходный код, который у вас нет. Например, происходит прерывание в исключении, или стек вызовов используется для перехода к исходному расположению.

Примечание.

  • Создание исходного кода (декомпиляция) возможно только для приложений .NET и построено на проекте ILSpy с открытым кодом.
  • Декомпиляция доступна только в Visual Studio 2019 версии 16.5 и более поздних версий.
  • Атрибут SuppressIldasmAttribute, примененный к сборке или модулю, не позволит Visual Studio выполнить декомпиляцию. Хотя атрибут устарел в .NET 6 и более поздних версиях, Visual Studio учитывает атрибут.

Создание исходного кода

Если при выполнении отладки исходный код недоступен, в Visual Studio отображается документ Исходный код не найден, а если отсутствуют символы для сборки, отображается документ Символы не загружены. Оба документа имеют параметр Декомпилировать исходный код, который создает код C# для текущего расположения. Созданный код C# можно использовать так же, как любой другой исходный код. Вы можете просматривать этот код, проверять переменные, устанавливать точки останова и т. д.

Символы не загружены

На следующем рисунке показано сообщение Символы не загружены.

Screenshot of no symbol loaded document

Исходный код не найден

На следующем рисунке показано сообщение Исходный код не найден.

Screenshot of source not found document

Код автокомпилирования

Начиная с Visual Studio 2022 версии 17.7 отладчик Visual Studio поддерживает автоматическую компиляцию внешнего кода .NET. При переходе во внешний код или при использовании окна стека вызовов можно выполнить автоматическую компиляцию.

При переходе к коду, который был реализован внешним образом, отладчик автоматически декомпилирует его и отображает текущую точку выполнения. Если вы хотите перейти во внешний код, необходимо отключить только мой код .

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

Чтобы выполнить автоматическую компиляцию из окна стека вызовов, выполните следующие действия.

  1. При отладке с открытым окном "Стек вызовов" выберите "Показать внешний код".

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

    Screenshot of Call Stack window showing external code.

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

    Screenshot of External Sources node showing decompiled assemblies.

    Вы можете выполнить отладку декомпилированного кода и задать точки останова.

Чтобы отключить автоматическую декомпиляцию внешнего кода, перейдите к разделу "Параметры > отладки > инструментов>" "Общие" и отмените автоматическую компиляцию в источник при необходимости (только управляемая версия).

Создание и внедрение исходного кода для сборки

Можно создать не только исходный код для определенного расположения, но и весь исходный код для конкретной сборки .NET. Чтобы выполнить эту задачу, перейдите в окно "Модули" и в контекстном меню сборки .NET, а затем выберите команду decompile Source to Symbol File . Visual Studio создает файл символов для сборки, а затем внедряет исходный код в файл символов. На последующем этапе можно извлечь внедренный исходный код.

Screenshot of assembly context menu in modules window with decompile source command.

Извлечение и просмотр внедренного исходного кода

Исходные файлы, внедренные в файл символов, можно извлечь с помощью команды Извлечь исходный код в контекстном меню окна Модули.

Screenshot of assembly context menu in modules window with extract sources command.

Извлеченные исходные файлы добавляются в решение как прочие файлы. В Visual Studio функция "Прочие файлы" по умолчанию отключена. Чтобы включить эту функцию, установите флажок Инструменты>Параметры>Среда>Документы>Показывать прочие файлы в Обозревателе решений. Если эта функция не включена, не удается открыть извлеченный исходный код.

Screenshot of tools option page with miscellaneous files option enabled.

Извлеченные исходные файлы отображаются в разделе прочих файлов в Обозревателе решений.

Screenshot of solution explorer with miscellaneous files.

Для библиотек .NET или пакетов NuGet, включенных для SourceLink, можно также выполнять по шагам исходный код, задавать точки останова и использовать все функции отладчика. Дополнительные сведения см. в разделе "Включение отладки и диагностика с помощью исходного канала" и "Улучшение производительности во время отладки" с помощью SourceLink.

Известные ограничения

Требуется режим прерывания выполнения

Создание исходного кода с помощью декомпиляции возможно только в том случае, если отладчик находится в режиме прерывания выполнения и приложение приостановлено. Например, Visual Studio переходит в режим прерывания, попадая в точку останова или в исключение. Вы можете легко активировать Visual Studio, чтобы разорвать следующий раз, когда код выполняется с помощью команды Break All (Break all icon).

Ограничения декомпиляции

Создание исходного кода из промежуточного языка (IL), используемого в сборках .NET, имеет некоторые внутренние ограничения. Поэтому созданный исходный код не выглядит в точности как оригинальный исходный код. Большая часть различий сосредоточена в тех местах, где информация в оригинальном исходном коде не нужна во время выполнения. Например, во время выполнения не нужна такая информация, как пробелы, комментарии и имена локальных переменных. Рекомендуется использовать созданный исходный код, чтобы понять, как выполняется программа, а не в качестве замены оригинального исходного кода.

Отладка оптимизированных сборок или сборок выпуска

При отладке кода, декомпилированного из сборки, скомпилированной с помощью оптимизаций компилятора, могут возникнуть следующие проблемы:

  • Точки останова могут не всегда привязаться к сопоставлению расположения источника данных.
  • Пошаговое выполнение может не всегда выполняться в правильном расположении.
  • Локальные переменные могут не иметь точных имен.
  • Некоторые переменные могут быть недоступны для оценки.

Дополнительные сведения можно найти в проблеме GitHub: интеграция ICSharpCode.Decompiler с ОТладчиком VS.

Надежность декомпиляции

Относительно небольшой процент попыток декомпиляции может привести к сбою. Это поведение связано с ошибкой null-ссылочной точки последовательности в ILSpy. Мы устранили этот сбой путем перехвата таких проблем и корректного завершения попытки декомпиляции.

Дополнительные сведения можно найти в проблеме GitHub: интеграция ICSharpCode.Decompiler с ОТладчиком VS.

Ограничения при работе с асинхронным кодом

Результаты декомпиляции модулей с шаблонами кода async/await могут быть неполными или завершаются сбоем. Шаблоны кода async/await и машины состояния yield state-machine в ILSpy реализованы только частично.

Дополнительные сведения можно найти в проблеме с GitHub: состояние генератора PDB.

Только мой код

Параметр Just My Code (JMC) позволяет Visual Studio перешагировать системные, платформы, библиотеки и другие вызовы, не являющиеся пользователями. Во время сеанса отладки в окне Модули отображаются модули кода, которые отладчик воспринимает как "Мой код" (т. е. пользовательский код).

Декомпиляция оптимизированных или выпускных модулей создает неиспользуемый код. Если отладчик прерывает работу в коде неиспользуемого неиспользуемого кода, например, откроется окно "Нет источника ". Чтобы отключить режим "Только мой код", перейдите в раздел Инструменты>Параметры (или Отладка>Параметры) >Отладка>Общие и снимите флажок Включить только мой код.

Извлеченный исходный код

Исходный код, извлеченный из сборки, имеет следующие ограничения.

  • Имена и расположение созданных файлов нельзя настроить.
  • Файлы являются временными и удаленными Visual Studio.
  • Файлы помещаются в одну папку без использования какой-либо иерархии, которая была в оригинальных исходных файлах.
  • Имя каждого файла содержит хэш контрольной суммы файла.

Создается только код C#

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