Visual Studio intern felsökningsvisualisering (natvis) för C++/WinRT

C++/WinRT Visual Studio Extension (VSIX) ger dig Visual Studios inbyggda felsökningsvisualisering (natvis) för C++/WinRT-projicerade typer. Detta ger dig en upplevelse som liknar C#-felsökning.

Note

Mer information om VSIX (C++/WinRT Visual Studio Extension) finns i Visual Studio stöd för C++/WinRT och VSIX.

Aktivering av Natvis

Natvis aktiveras automatiskt för en felsökningsversion eftersom WINRT_NATVIS definieras när _DEBUG-symbolen definieras.

Så här aktiverar du det för en releaseversion.

  • Kompilera koden med symbolen WINRT_NATVIS definierad. På så sätt exporteras en WINRT_abi_val funktion, som tillhandahåller startpunkten för felsökningsvisualiseraren för att utvärdera egenskapsvärden i målprocessen.
  • Generera en fullständig PDB. Det beror på att felsökningsvisualiseraren använder Visual Studio C++ Expression Evaluator, som i sin tur kräver symboliska definitioner för visade egenskapstyper.
  • En typ som visualiseras måste ange en körningsklass eller ett gränssnitt som definieras i upptäckbara metadata. Den gör detta via implementeringen av IInspectable::GetRuntimeClassName.

Med tanke på ovanstående fungerar felsökningsvisualiseraren bäst med Windows systemtyper för vilka metadata kan hittas i C:\Windows\System32\WinMetadata mappen. Den kan dock också stödja användardefinierade typer och fjärrfelsökning, förutsatt att du hittar .winmd filer korrekt.

Använda anpassade metadata

Felsökningsvisualiseraren söker efter användardefinierade metadata (.winmd filer) tillsammans med processen .exe. Den använder en algoritm som liknar RoGetMetaDataFile och söker efter efterföljande delsträngar av det fullständigt kvalificerade typnamnet. Till exempel, om typen som visualiseras är Contoso.Controls.Widget, söker visualiseraren, i tur och ordning, efter:

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

Fjärrfelsökning med anpassade metadata

Vid fjärrfelsökning är processen .exe inte lokal, så sökningen efter anpassade metadata (som nämns i föregående avsnitt) misslyckas. I så fall återgår visualiseraren till en lokal cachemapp (%TEMP%) för en lämplig .winmd fil. Om den hittar en registrerar den filens storlek och datum och söker sedan i fjärrfelsökningsmålet efter samma .winmd tillsammans med binärfilen. Om det behövs laddas fjärrfilen ned och uppdaterar den lokala cachen. Den här strategin säkerställer att den lokalt cachelagrade .winmd alltid är uppdaterad, samt tillhandahåller ett sätt att manuellt cachelagra en . winmd om det inte går att hitta den via fjärranslutning (till exempel om F5-distributionen inte placerade den där).

Ett exempel på cachelagringsbeteendet finns i avsnittet Felsökning nedan.

Felsökning

Felsökningsvisualiseraren använder Visual Studio C++ Expression Evaluator för att anropa den exporterade WINRT_abi_val-funktionen för att hämta egenskapsvärden. Normalt kan visualiseraren fånga ohanterade undantag och försämras på ett korrekt sätt, vilket visar "<Objekt som inte är initierat eller information är inte tillgängligt>" i Visual Studio Watch-fönster.

Det är användbart när visualiseraren försöker utvärdera en lokal variabel utanför dess livslängdsomfång (till exempel före konstruktion). I vissa sammanhang, till exempel enhetstester, installeras ett ohanterat undantagsfilter. Detta kan leda till att processen avslutas när C++-uttrycksutvärderingen felar. För att förhindra fel gör visualiseraren flera VirtualQuery-anrop i WINRT_abi_val.

Diagnostik

Om en egenskap inte visas korrekt aktiverar du utförlig Natvis-diagnostik i Visual Studio (Verktyg>Alternativ>Felsökning>Utdatafönster>Diagnostikmeddelanden för Natvis) och kontrollerar sedan fönstret Utdata efter Natvis-fel.

Följande utdrag visar flera försök att söka efter en .winmd fil, följt av en nedladdning från fjärrmålet till den lokala cachemappen och sedan en inläsning av .winmd filen.

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

Om visualiseraren inte hittar en .winmd fil genereras det här felet:

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

Det finns ett antal andra felscenarier som alla producerar diagnostik.

Om metadata är tillgängliga visar utdatadiagnostiken många anrop så här:

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

Det första är ett anrop till IStringable.ToString för att hämta strängrepresentationen av en komplex typ (det oexpanderade visningsvärdet).

Det andra är ett anrop till IInspectable::GetRuntimeClassName för att reflektera över typens egenskaper.

Efterföljande anrop till WINRT_abi_val är utvärderingar av egenskaper för varje gränssnitt som upptäcks för typen.

Anrop av WINRT_abi_val

Du kan använda windows Visual Studio Immediate/Command för att direkt anropa WINRT_abi_val för felsökning.

Till exempel, givet den projicerade variabeln stringable, kan du utvärdera dess IStringable.ToString så här:

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