Нативная визуализация отладки (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"