Нативная визуализация отладки (natvis) Visual Studio для C++/WinRT

Расширение C++/WinRT для Visual Studio (VSIX) позволяет выполнять нативную визуализацию отладки (natvis) Visual Studio для проектируемых типов C++/WinRT. Это обеспечивает возможности, аналогичные отладке C#.

Примечание.

Дополнительные сведения о расширении C++/WinRT для Visual Studio (VSIX) см. в разделе Поддержка C++/WinRT и VSIX в Visual Studio.

Включение natvis

Natvis автоматически включен для отладочной сборки, так как WINRT_NATVIS определяется, если определен символ _DEBUG.

Ниже описано, как воспользоваться сборкой выпуска.

  • Скомпилируйте код с определенным символом WINRT_NATVIS. Выполнится экспорт функции WINRT_abi_val, которая предоставляет визуализатору отладки точку входа для оценки значений свойств в целевом процессе.
  • Создайте полный PDB-файл. Это связано с тем, что визуализатор отладки использует средство оценки выражений C++ для Visual Studio, которое требует наличия символьных определений для отображаемых типов свойств.
  • Визуализированный тип должен сообщать о классе среды выполнения или интерфейсе, определенном в обнаруживаемых метаданных. Это достигается посредством реализации IInspectable::GetRuntimeClassName.

Если учитывать приведенное выше, визуализатор отладки оптимально работает с типами систем Windows, метаданные для которых можно найти в папке C:\Windows\System32\WinMetadata. Но он также может поддерживать определяемые пользователем типы и удаленную отладку, если вы укажете точное расположение файлов .winmd.

Использование пользовательских метаданных

Визуализатор отладки ищет определяемые пользователем метаданные (файлы .winmd) и процесс .exe. Он использует алгоритм, аналогичный RoGetMetaDataFile, для проверки последовательных подстрок полного имени типа. Например, если визуализируется тип Contoso.Controls.Widget, визуализатор ищет следующее в таком порядке:

  • Contoso.Controls.Widget.winmd
  • Contoso.Controls.winmd
  • Contoso.winmd

Удаленная отладка с помощью пользовательских метаданных

При удаленной отладке процесс .exe не является локальным, поэтому поиск пользовательских метаданных (упомянутых в предыдущем разделе) завершается сбоем. В этом случае визуализатор вернется к папке локального кэша (%TEMP%) для поиска подходящего файла .winmd. Если такой файл будет найден, визуализатор записывает размер и дату файла, а затем в удаленной целевой системе отладки выполняет поиск такого же файла .winmd вместе с двоичным файлом. При необходимости выполняется скачивание удаленного файла, что приводит к обновлению локального кэша. Эта стратегия гарантирует, что локально кэшированные .winmd данные всегда актуальны, а также предоставляют средства для кэширования вручную.winmd если файл не удается найти в удаленной системе (например, если развертывание F5 не поместило его там).

Пример поведения кэширования см. в разделе Устранение неполадок ниже.

Устранение неполадок

Визуализатор отладки использует средство оценки выражений C++ в Visual Studio для вызова экспортированной функции WINRT_abi_val с целью получения значений свойств. Как правило, визуализатор может перехватывать необработанные исключения и безопасно завершать работу с отображением сообщения <Объект не инициализирован или данные недоступны> в окнах Контрольные значения в Visual Studio.

Это полезно, когда визуализатор пытается оценить локальную переменную за пределами ее жизненного цикла (например, перед построением). В некоторых контекстах, таких как модульные тесты, устанавливается необработанные фильтры исключений. Это может привести к завершению процесса при сбое средства оценки выражений C++. Чтобы предотвратить возникновение сбоев, визуализатор выполняет несколько вызовов VirtualQuery в WINRT_abi_val.

Диагностика

Если свойство отображается неправильно, включите подробную диагностику natvis в Visual Studio (Средства>Параметры>Отладка>Окно вывода>Диагностические сообщения natvis), а затем отслеживайте ошибки natvis в окне Вывод.

В следующем фрагменте показано несколько попыток поиска файла .winmd, последующее его скачивание из удаленной целевой системы в локальную папку кэша и загрузка этого файла .winmd.

Natvis C++/WinRT: Looking for C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.Widget.winmd
Natvis C++/WinRT: Looking for C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.winmd
Natvis C++/WinRT: Downloading C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.winmd
Natvis C++/WinRT: Loaded C:\Users\...\AppData\Local\Temp\Consoso.Controls.winmd

Если визуализатору не удается найти файл .winmd, возникает такая ошибка:

Natvis C++/WinRT: Could not find metadata for Consoso.Controls.Widget

Существует ряд других сценариев ошибок, которые предоставляют данные диагностики.

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

Natvis C++/WinRT: WINRT_abi_val(*(::IUnknown**)0x32dd4ffc18, L"{96369F54-8EB6-48F0-ABCE-C1B211E627C3}", 0).s,sh
Natvis C++/WinRT: WINRT_abi_val(*(::IUnknown**)0x32dd4ffc18, L"{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}", -2).s,sh

Первый — вызов IStringable.ToString для получения строкового представления сложного типа (неразвернутое отображаемое значение).

Второй — вызов IInspectable::GetRuntimeClassName для отражения свойств типа.

Последующие вызовы WINRT_abi_val — это оценки свойств для каждого интерфейса, обнаруженного в типе.

Вызов WINRT_abi_val

Вы можете использовать окна Visual Studio Немедленно/Команда для прямого вызова WINRT_abi_val с целью устранения неполадок.

Например, при наличии проецируемой переменной stringable вы можете оценить ее IStringable.ToString следующим образом:

>? WINRT_abi_val((::IUnknown*)&stringable, L"{96369F54-8EB6-48F0-ABCE-C1B211E627C3}", 0).s,sh
L"string"