Поделиться через


Отладка пользовательского кода с помощью функции "Только мой код"

Только мой код — это функция отладки Visual Studio, которая автоматически обходит вызовы системы, платформы и другой непользовательский код. В окне Стек вызовов функция "Только мой код" сворачивает такие вызовы во фреймы [Внешний код].

Просто мой код работает по-разному в проектах .NET и C++.

Включение или отключение только моего кода

Для большинства языков программирования режим "Только мой код" включен по умолчанию.

  • Чтобы включить или выключить режим "Только мой код" в Visual Studio, в разделе Инструменты>Параметры (или Отладка>Параметры) >Отладка>Общие установите или снимите флажок Включить только мой код.

Снимок экрана флажка

Снимок экрана флажка

Примечание.

Параметр Включить только мой код является глобальным параметром, который применяется ко всем проектам Visual Studio на всех языках.

отладка "Только мой код"

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

Снимок экрана с пользовательским кодом в окне

Снимок экрана с пользовательским кодом в окне

В окнах Стек вызовов и Задачи функция "Только мой код" сворачивает непользовательский код в затененный аннотированный фрейм кода, помеченный как [External Code].

Снимок экрана с элементом

Снимок экрана с элементом

Совет

Открывать окна Модули, Стек вызовов и Задачи, как и большинство других окон отладки, можно только в сеансе отладки. В сеансе отладки выберите окна, которые нужно открыть, в разделе Отладка>Окна.

Чтобы просмотреть код в свернутом фрейме [Внешний код], щелкните правой кнопкой мыши окно Стек вызовов или Задачи и выберите в контекстном меню пункт Показать внешний код. Вместо фрейма [Внешний код] появятся развернутые строки внешнего кода.

Снимок экрана с элементом

Снимок экрана с элементом

Примечание.

Параметр Показать внешний код является текущим пользовательским параметром профилировщика, который применяется ко всем проектам на всех языках, открываемых этим пользователем.

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

Начиная с Visual Studio 2022 версии 17.7, можно автокомпилировать код .NET, дважды щелкнув внешний код в окне стека вызовов. Дополнительные сведения см. в статье "Создание исходного кода из сборок .NET во время отладки".

"Только мой код" в .NET

В проектах .NET функция "Только мой код" определяет пользовательский и непользовательский код, исходя из файлов символов (.pdb) и оптимизаций программ. Отладчик .NET считает оптимизированные двоичные файлы и незагруженные файлы .pdb непользовательским кодом.

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

  • DebuggerNonUserCodeAttribute сообщает отладчику, что код, к которому применен этот атрибут, не является пользовательским.
  • DebuggerHiddenAttribute скрывает код от отладчика, даже если режим "Только мой код" включен.
  • DebuggerStepThroughAttribute указывает отладчику пошагово пройти через код, к которому применен этот атрибут, а не выполнять шаг с заходом в процедуры.

Весь остальной код отладчик .NET рассматривает как пользовательский.

При отладке в .NET:

  • Если выбрать Отладка>Шаг с заходом (или нажать клавишу F11) в непользовательском коде, будет выполнен шаг с обходом процедур и переход на следующую строку пользовательского кода.
  • Если выбрать Отладка>Шаг с выходом (или нажать клавиши Shift+F11) в непользовательском коде, будет выполнен переход на следующую строку пользовательского кода.

Если пользовательского кода больше нет, будет продолжена отладка (до завершения или до достижения другой точки останова) либо появится сообщение об ошибке.

Если отладчик прерывается в непользовательском коде (например, вы выбрали Отладка>Прервать все и приостановили выполнение в непользовательском коде), появляется окно Нет источника. Затем вы можете использовать команду Отладка>Шаг, чтобы перейти к следующей строке пользовательского кода.

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

Если для этого исключения включена первичная обработка исключения, вызывающая строка пользовательского кода в исходном коде выделяется зеленым цветом. В окне Стек вызовов отображается аннотированный фрейм с меткой [Внешний код].

C++ просто мой код

Функция "Только мой код" для пошагового выполнения кода поддерживается начиная с Visual Studio 2017 версии 15.8. Чтобы использовать эту функцию, необходимо включить параметр компилятора /JMC (отладка "Только мой код"). В проектах C++ этот параметр включен по умолчанию. Для окна стека вызовов и поддержки стека вызовов в Just My Code переключатель /JMC не требуется.

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

В отношении функционирования стека вызовов, например в окне Стек вызовов, в режиме "Только мой код" в C++ непользовательским кодом считаются только следующие функции.

  • Функции с открытой исходной информацией в файле символов.
  • Функции, в которых файлы символов указывают на отсутствие исходного файла, соответствующего кадру стека.
  • Функции, указанные в файлах *.natjmc в папке %VsInstallDirectory%\Common7\Packages\Debugger\Visualizers.

Что касается пошагового выполнения кода, в режиме "Только мой код" в C++ непользовательским кодом считаются только следующие функции.

  • Функции, для которых соответствующий PDB-файл не загружен в отладчик.
  • Функции, указанные в файлах *.natjmc в папке %VsInstallDirectory%\Common7\Packages\Debugger\Visualizers.

Примечание.

Для поддержки пошагового выполнения кода в режиме "Только мой код" код C++ должен быть скомпилирован с использованием компиляторов MSVC в Visual Studio 15.8 предварительной версии 3 или более поздней версии, и должен быть включен параметр компилятора /JMC (он включен по умолчанию). Дополнительные сведения см. в разделе Настройка поведения стека вызовов и пошагового выполнения кода в C++ и в этой записи блога. Если код был скомпилирован с использованием более старого компилятора, файлы .natstepfilter являются единственным способом настройки пошагового выполнения кода, который не зависит от режима "Только мой код". См. раздел Настройка поведения пошагового выполнения кода C++.

Во время отладки C++ непользовательский код пропускается по умолчанию. Во время отладки C++:

  • Отладка>шага ( или F11) на шагах, отличных от пользователя, поверх кода или выполняется в следующей строке пользовательского кода, если step Into вызывается из кода, отличного от пользователя.
  • Шаг отладки>(или shift+F11) в коде, отличном от пользователя, выполняется в следующей строке пользовательского кода (за пределами текущего кадра стека).

Если пользовательского кода больше нет, будет продолжена отладка (до завершения или до достижения другой точки останова) либо появится сообщение об ошибке.

Если отладчик прерывается в непользовательском коде (например, вы выбрали Отладка>Прервать все и приостановили выполнение в непользовательском коде), пошаговое выполнение продолжается в непользовательском коде.

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

Настройка стека вызовов C++ и поведения пошагового выполнения кода

В проектах C++ можно указывать модули, исходные файлы и функции, которые окно Стек вызовов будет считать непользовательским кодом. Для этого нужно указать их в файлах *.natjmc. Эта настройка также применяется к шагу кода, если используется последний компилятор (см. раздел C++ Just My Code).

  • Чтобы указать непользовательский код для всех пользователей компьютера с Visual Studio, добавьте файл .natjmc в папку %VsInstallDirectory%\Common7\Packages\Debugger\Visualizers.
  • Чтобы указать непользовательский код для отдельного пользователя, добавьте файл .natjmc в папку %USERPROFILE%\My Documents\<Версия Visual Studio>\Visualizers.

Файл .natjmc является XML-файлом и имеет следующий синтаксис.

<?xml version="1.0" encoding="utf-8"?>
<NonUserCode xmlns="http://schemas.microsoft.com/vstudio/debugger/jmc/2015">

  <!-- Modules -->
  <Module Name="ModuleSpec" />
  <Module Name="ModuleSpec" Company="CompanyName" />

  <!-- Files -->
  <File Name="FileSpec"/>

  <!-- Functions -->
  <Function Name="FunctionSpec" />
  <Function Name="FunctionSpec" Module ="ModuleSpec" />
  <Function Name="FunctionSpec" Module ="ModuleSpec" ExceptionImplementation="true" />

</NonUserCode>

Атрибуты элементов модуля

Атрибут Description
Name Обязательное. Полный путь к модулю или модулям. Вы можете использовать следующие подстановочные знаки Windows: ? (от 0 до 1 символа) и * (от 0 до нескольких символов). Например,

<Module Name="?:\3rdParty\UtilLibs\*" />

указывает отладчику, что необходимо рассматривать все модули в \3rdParty\UtilLibs на любом диске как внешний код.
Company Необязательно. Название компании, публикующей модуль, внедренный в исполняемый файл. Этот атрибут можно использовать для устранения неоднозначности модулей.

Атрибуты элементов файла

Атрибут Description
Name Обязательное. Полный путь к файлу или файлам исходного кода, который необходимо считать внешним кодом. При задании пути можно использовать следующие подстановочные знаки Windows: ? и *.

Атрибуты элементов функций

Атрибут Description
Name Обязательное. Полное имя функции, которую необходимо рассматривать как внешний код. ou может использовать дикие символы ? Windows карта и * при указании пути.
Module Необязательно. Имя модуля или полный путь к модулю, содержащему эту функцию. Этот атрибут можно использовать для устранения неоднозначности функций с одинаковыми именами.
ExceptionImplementation Если задано значение true, стек вызовов отображает функцию, которая создала исключение, а не данную функцию.

Настройка поведения шагов C++ независимо от параметров JIT

В проектах C++ можно указать функции для пошагового выполнения, перечислив их как функции NoStepInto в файлах *.natstepfilter . Функции, перечисленные в файлах *.natstepfilter , не зависят от параметров just My Code. Функция NoStepInto сообщает отладчику выполнить шаг над функцией, даже если он вызывает некоторые функции StepInto или другой пользовательский код. В отличие от функций, перечисленных в .natjmc, отладчик переходит в первую строку пользовательского кода в функции NoStepInto.

  • Чтобы указать непользовательский код для всех локальных пользователей Visual Studio, добавьте файл .natstepfilter в папку %VsInstallDirectory%\Common7\Packages\Debugger\Visualizers.
  • Чтобы указать непользовательский код для отдельного пользователя, добавьте файл .natstepfilter в папку %USERPROFILE%\My Documents\<Версия Visual Studio>\Visualizers.

Примечание.

Некоторые сторонние расширения могут отключить функции .natstepfilter .

Файл .natstepfilter является XML-файлом и имеет следующий синтаксис.

<?xml version="1.0" encoding="utf-8"?>
<StepFilter xmlns="http://schemas.microsoft.com/vstudio/debugger/natstepfilter/2010">
    <Function>
        <Name>FunctionSpec</Name>
        <Action>StepAction</Action>
    </Function>
    <Function>
        <Name>FunctionSpec</Name>
        <Module>ModuleSpec</Module>
        <Action>StepAction</Action>
    </Function>
</StepFilter>

Элемент Description
Function Обязательное. Указывает одну или несколько функций как функцию, не написанную пользователем.
Name Обязательно. Регулярное выражение в формате ECMA-262, содержащее полное имя функции для сопоставления. Например:

<Name>MyNS::MyClass::.*</Name>

сообщает отладчику, что все методы в MyNS::MyClass, должны считаться кодом, не написанным пользователем. Сопоставление учитывает регистр.
Module Необязательно. Регулярное выражение в формате ECMA-262, указывающее полный путь к модулю, содержащему функцию. Сопоставление не учитывает регистр.
Action Обязательно. Одно из следующих чувствительных к регистру значений:

NoStepInto — указывает отладчику, что необходимо пройти соответствующую функцию без остановки.
StepInto — указывает отладчику, что необходимо осуществлять пошаговое выполнение с заходом в соответствующие функции. Это значение отменяет все остальные значения NoStepInto для соответствующей функции.

Дополнительные сведения о файлах .natstepfilter и .natjmc

  • Начиная с Visual Studio 2022 версии 17.6, можно добавлять файлы .natjmc и .natstepfilter непосредственно в решение или проект.

  • Синтаксические ошибки в файлах .natstepfilter и natjmc не сообщаются в окне вывода отладчика.

  • В отличие от файлов natvis , natstepfilter и natjmc-файлов не загружаются в режиме горячей перезагрузки. Вместо этого эти файлы перезагрузятся в начале сеанса отладки.

  • Для функций шаблона может быть полезно использовать &lt;.*&gt; или &lt;.* в имени.

JavaScript Just My Code

Для проектов .esproj в Visual Studio 2022 Visual Studio Code использует файл launch.json для настройки и настройки отладчика. launch.json — это файл конфигурации отладчика.

Visual Studio подключает отладчик только к пользовательскому коду. Для проектов .esproj можно настроить пользовательский код (т . е. параметры JIT ) в Visual Studio с помощью skipFiles параметра в launch.json. Этот параметр работает так же, как и параметры launch.json в VS Code. Дополнительные сведения о skipFiles см. в разделе "Пропуск неинтересного кода".