Visual Studio visualisasi debug asli (natvis) untuk C++/WinRT

C++/WinRT Visual Studio Extension (VSIX) memberi Anda visualisasi debug asli Visual Studio (natvis) dari jenis proyeksi C++/WinRT. Ini memberi Anda pengalaman yang mirip dengan penelusuran kesalahan C#.

Catatan

Untuk informasi selengkapnya tentang C++/WinRT Visual Studio Extension (VSIX), lihat Dukungan Visual Studio untuk C++/WinRT, dan VSIX.

Mengaktifkan natvis

Natvis secara otomatis aktif untuk build debug karena WINRT_NATVIS ditentukan saat simbol _DEBUG ditentukan.

Berikut cara memilih untuk build rilis.

  • Kompilasi kode Anda dengan simbol WINRT_NATVIS ditentukan. Melakukannya mengekspor fungsi WINRT_abi_val , yang menyediakan titik masuk bagi visualizer debug untuk mengevaluasi nilai properti dalam proses target.
  • Buat PDB lengkap. Ini karena visualizer debug menggunakan Visual Studio C++ Expression Evaluator, yang pada gilirannya memerlukan definisi simbolis untuk jenis properti yang ditampilkan.
  • Jenis yang divisualisasikan harus melaporkan kelas runtime atau antarmuka yang ditentukan dalam metadata yang dapat ditemukan. Ini dilakukan melalui implementasi IInspectable::GetRuntimeClassName.

Mengingat hal di atas, visualizer debug berfungsi paling baik dengan jenis sistem Windows yang metadatanya C:\Windows\System32\WinMetadata dapat ditemukan di folder. Namun, ini juga dapat mendukung jenis yang ditentukan pengguna dan penelusuran kesalahan jarak jauh, asalkan Anda menemukan .winmd file dengan benar.

Menggunakan metadata kustom

Visualizer debug mencari metadata (.winmd file) yang ditentukan pengguna bersama proses .exe. Ini menggunakan algoritma yang mirip dengan RoGetMetaDataFile, memeriksa substring berturut-turut dari nama jenis yang sepenuhnya memenuhi syarat. Misalnya, jika jenis yang divisualisasikan adalah Contoso.Controls.Widget, maka visualizer terlihat, secara berurutan, untuk:

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

Penelusuran kesalahan jarak jauh dengan metadata kustom

Saat penelusuran kesalahan jarak jauh, prosesnya .exe tidak lokal, sehingga pencarian metadata kustom (disebutkan di bagian sebelumnya) gagal. Dalam hal ini, visualizer kembali ke folder cache lokal (%TEMP%) untuk file yang sesuai .winmd . Jika menemukannya, maka ia merekam ukuran dan tanggal file, lalu mencari target penelusuran kesalahan jarak jauh untuk hal yang sama .winmd bersama biner. Jika perlu, file jarak jauh diunduh, memperbarui cache lokal. Strategi ini memastikan bahwa cache .winmd lokal selalu diperbarui, serta menyediakan sarana untuk menyimpan cache secara manual .winmd jika tidak dapat ditemukan dari jarak jauh (misalnya, jika penyebaran F5 tidak meletakkannya di sana).

Untuk contoh perilaku penembolokan, lihat bagian Pemecahan Masalah di bawah ini.

Pemecahan Masalah

Visualizer debug menggunakan Visual Studio C++ Expression Evaluator untuk memanggil fungsi WINRT_abi_val yang diekspor untuk mendapatkan nilai properti. Biasanya, visualizer dapat menangkap pengecualian yang tidak tertangani, dan menurun dengan baik, menampilkan "<Objek yang tidak diinisialisasi atau informasi tidak tersedia>" di jendela Visual Studio Watch .

Itu berguna ketika visualizer mencoba mengevaluasi variabel lokal di luar cakupan masa pakainya (misalnya, sebelum konstruksi). Dalam beberapa konteks, seperti pengujian unit, filter pengecualian yang tidak tertangani diinstal. Ini dapat menyebabkan proses berakhir ketika kesalahan evaluator ekspresi C++. Untuk mencegah kesalahan, visualizer melakukan beberapa panggilan VirtualQuery dalam WINRT_abi_val.

Diagnostik

Jika properti tidak ditampilkan dengan benar, aktifkan diagnostik natvis verbose di Visual Studio (Opsi>Alat>Men-debug pesan diagnostik Natvis Jendela>Output Debugging>), lalu amati jendela Output untuk kesalahan natvis.

Kutipan berikut menunjukkan beberapa upaya untuk .winmd memeriksa file, diikuti dengan unduhan dari target jarak jauh ke folder cache lokal, lalu memuat file tersebut .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

Jika visualizer gagal menemukan .winmd file, maka kesalahan ini dihasilkan:

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

Ada sejumlah skenario kesalahan lainnya yang semuanya menghasilkan diagnostik.

Jika metadata tersedia, maka diagnostik output akan menampilkan banyak panggilan seperti ini:

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

Yang pertama adalah panggilan ke IStringable.ToString untuk mendapatkan representasi string dari jenis kompleks (nilai tampilan yang tidak terlampir).

Yang kedua adalah panggilan ke IInspectable::GetRuntimeClassName, untuk merefleksikan properti jenis.

Panggilan WINRT_abi_val berikutnya adalah evaluasi properti untuk setiap antarmuka yang ditemukan pada jenis tersebut.

Memanggil WINRT_abi_val

Anda dapat menggunakan jendela Perintah Langsung/Visual Studio untuk langsung memanggil WINRT_abi_val untuk pemecahan masalah.

Misalnya, mengingat variabel yang diproyeksikan dapat di-stringable, Anda dapat mengevaluasi IStringable.ToString-nya sebagai:

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