Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
#B0 #A1 #A2 Logotyp för felsökning av tidsresor med en klocka. #A3 #A4 #C5
Det här labbet introducerar TTD (Time Travel Debugging) med hjälp av ett litet exempelprogram med ett kodfel. TTD används för att felsöka, identifiera och fastställa grundorsaken till problemet. Även om problemet i det här lilla programmet är lätt att hitta kan den allmänna proceduren användas för mer komplex kod. Den här allmänna proceduren kan sammanfattas på följande sätt.
- Samla in en spårning av tidsresan för det misslyckade programmet.
- Använd kommandot dx (Display Debugger Object Model Expression) för att hitta undantagshändelsen som lagras i inspelningen.
- Använd kommandot !tt (tidsresa) för att resa till platsen för undantagshändelsen i spårningen.
- Från den punkten, spåra steg för steg bakåt tills den felaktiga koden i fråga kommer i fokus.
- Med felkoden i omfånget kan du titta på de lokala värdena och utveckla en hypotes för en variabel som kan innehålla ett felaktigt värde.
- Fastställ minnesadressen för variabeln med det felaktiga värdet.
- Ange en brytpunkt för minnesåtkomst (ba) på adressen till den misstänkta variabeln med hjälp av kommandot ba (Break on Access).
- Använd g – för att köra tillbaka till den sista minnesåtkomstpunkten för den misstänkta variabeln.
- Se om den platsen, eller några instruktioner tidigare, är punkten där kodfelet uppstår. I så fall är du klar. Om det felaktiga värdet kom från någon annan variabel anger du ytterligare en brytpunkt för åtkomstbrytpunkten för den andra variabeln.
- Använd g – för att köra tillbaka till den sista minnesåtkomstpunkten på den andra misstänkta variabeln. Se om platsen eller några instruktioner innan innehåller kodfelet. I så fall är du klar.
- Upprepa den här processen när du går tillbaka tills koden som anger det felaktiga värdet som orsakade felet finns.
Även om de allmänna tekniker som beskrivs i den här proceduren gäller för en bred uppsättning kodproblem, finns det unika kodproblem som kräver en unik metod. De tekniker som illustreras i genomgången bör användas för att utöka din felsökningsverktygsuppsättning och illustrerar en del av vad som är möjligt med en TTD-spårning.
Labbmål
När du har slutfört den här labbuppgiften kan du använda den allmänna proceduren med en spårning av tidsresor för att hitta problem i koden.
Labbkonfiguration
Du behöver följande maskinvara för att kunna slutföra labbet.
- En bärbar dator eller stationär dator (värd) som kör Windows 10 eller Windows 11
Du behöver följande programvara för att kunna slutföra labbet.
- The WinDbg. Information om hur du installerar WinDbg finns i WinDbg – Installation
- Visual Studio för att skapa C++-exempelkoden.
Labbet har följande tre avsnitt.
- Avsnitt 1: Skapa exempelkoden
- Avsnitt 2: Registrera en loggning av exemplet "DisplayGreeting"
- Avsnitt 3: Analysera spårningsfilinspelningen för att identifiera kodproblemet
Avsnitt 1: Skapa exempelkoden
I avsnitt 1 skapar du exempelkoden med hjälp av Visual Studio.
Skapa exempelappen i Visual Studio
I Microsoft Visual Studio klickar du på Arkiv>Nytt>projekt/lösning... och klickar på Visual C++ -mallarna.
Välj Win32-konsolprogrammet.
Ange ett projektnamn för DisplayGreeting och klicka på OK.
Avmarkera SDL-kontrollerna (Security Development Lifecycle).
Klicka på Slutför.
Klistra in följande text i fönstret DisplayGreeting.cpp i Visual Studio.
// DisplayGreeting.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <array> #include <stdio.h> #include <string.h> void GetCppConGreeting(wchar_t* buffer, size_t size) { wchar_t const* const message = L"HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL DEBUGGING!"; wcscpy_s(buffer, size, message); } int main() { std::array <wchar_t, 50> greeting{}; GetCppConGreeting(greeting.data(), sizeof(greeting)); wprintf(L"%ls\n", greeting.data()); return 0; }I Visual Studio klickar du på Project>DisplayGreeting-egenskaper. Klicka sedan på C/C++ och Kodgenerering.
Ange följande egenskaper.
Inställning Värde Säkerhetskontroll Inaktivera säkerhetskontroll (/GS-) Grundläggande körningskontroller Standardinställning Anmärkning
Även om den här inställningen inte rekommenderas är det möjligt att föreställa sig ett scenario där någon rekommenderar att du använder de här inställningarna för att påskynda kodningen eller för att underlätta vissa testmiljöer.
I Visual Studio klickar du på Skapa>bygglösning.
Om allt går bra bör byggfönstren visa ett meddelande som anger att bygget lyckades.
Leta upp de skapade exempelappfilerna
I Solution Explorer högerklickar du på projektet DisplayGreeting och väljer Öppna mapp i Utforskaren.
Navigera till mappen Debug som innehåller det kompilerade exe-filen och symbol-pdb-filen för exemplet. Du kan till exempel navigera till C:\Projects\DisplayGreeting\Debug, om det är mappen som dina projekt lagras i.
Kör exempelappen med kodfelet
Dubbelklicka på exe-filen för att köra exempelappen.
Om den här dialogrutan visas väljer du Stäng program
I nästa avsnitt av genomgången registrerar vi körningen av exempelappen för att se om vi kan avgöra varför det här undantaget inträffar.
Avsnitt 2: Registrera en spårning av exemplet "DisplayGreeting"
I avsnitt 2 registrerar du en spårning av den felaktiga exempelappen "DisplayGreeting"
Följ dessa steg för att starta exempelappen och registrera en TTD-spårning. Allmän information om hur du registrerar TTD-spårningar finns i Felsökning av tidsresor – Registrera en spårning
Kör WinDbg som administratör för att kunna registrera spårningar av tidsresor.
I WinDbg väljer du Fil>Starta felsökning>Starta körbar fil (avancerat).
Ange sökvägen till den användarmodus körbara filen som du vill registrera eller välj Bläddra för att navigera till den körbara filen. Information om hur du arbetar med den körbara startmenyn i WinDbg finns i WinDbg – Starta en session i användarläge.
Markera kryssrutan Record with Time Travel Debugging för att registrera en spårning när den körbara filen startas.
Klicka på Konfigurera och spela in för att starta inspelningen.
När dialogrutan "Konfigurera inspelning" visas, klickar du på Spela in för att starta den körbara filen och börja inspelningen.
Inspelningsdialogrutan visas som anger att spårningen registreras. Kort därefter kraschar programmet.
Klicka på Stäng program för att stänga dialogrutan "DisplayGreeting har slutat fungera".
När programmet kraschar stängs spårningsfilen och skrivs ut till disken.
Felsökningsprogrammet öppnar automatiskt spårningsfilen och indexerar den. Indexering är en process som möjliggör effektiv felsökning av spårningsfilen. Den här indexeringsprocessen tar längre tid för större spårningsfiler.
(5120.2540): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: D:0 [Unindexed] Index !index Indexed 10/22 keyframes Indexed 20/22 keyframes Indexed 22/22 keyframes Successfully created the index in 755ms.
Anmärkning
En nyckelram är en plats i en spårning som används för indexering. Nyckelrutor genereras automatiskt. Större spårningar innehåller fler nyckelramar.
Nu är du i början av spårningsfilen och är redo att färdas framåt och bakåt i tiden.
Nu när du har registrerat en TTD-spårning kan du spela upp spårningen igen eller arbeta med spårningsfilen, till exempel dela den med en medarbetare. Mer information om hur du arbetar med spårningsfiler finns i Felsökning av tidsresor – Arbeta med spårningsfiler
I nästa avsnitt av den här labbuppgiften analyserar vi spårningsfilen för att hitta problemet med vår kod.
Avsnitt 3: Analysera spårningsfilinspelningen för att identifiera kodproblemet
I avsnitt 3 analyserar du spårningsfilens inspelning för att identifiera kodproblemet.
Konfigurera WinDbg-miljön
Lägg till platsen för dina lokala symboler i sökvägen till symbolerna och ladda om symbolerna genom att skriva följande kommandon.
.sympath+ C:\MyProjects\DisplayGreeting\Debug .reloadLägg till din lokala kodplats i källsökvägen genom att skriva följande kommando.
.srcpath+ C:\MyProjects\DisplayGreeting\DisplayGreetingFör att kunna visa tillståndet för stacken och lokala variabler går du till menyfliksområdet WinDbg och väljer Visa och Lokala och Visa och Stack. Ordna fönstren så att du kan visa dem, källkoden och kommandofönstren samtidigt.
I menyfliksområdet WinDbg väljer du Källa och Fil med öppen källkod. Leta upp filen DisplayGreeting.cpp och öppna den.
Granska undantaget
När spårningsfilen lästes in visas information om att ett undantag inträffade.
2fa8.1fdc): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68ef8100 ebx=00000000 ecx=77a266ac edx=69614afc esi=6961137c edi=004da000 eip=77a266ac esp=0023f9b4 ebp=0023fc04 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:0023fac0=00000000Använd dx-kommandot för att visa en lista över alla händelser i inspelningen. Undantagshändelsen visas i händelserna.
0:000> dx -r1 @$curprocess.TTD.Events ... [0x2c] : Module Loaded at position: 9967:0 [0x2d] : Exception at 9BDC:0 [0x2e] : Thread terminated at 9C43:0 ...Anmärkning
I den här genomgången används tre perioder för att indikera att överflödiga utdata har tagits bort.
Klicka på undantagshändelsen för att visa information om TTD-händelsen.
0:000> dx -r1 @$curprocess.TTD.Events[17] @$curprocess.TTD.Events[17] : Exception at 68:0 Type : Exception Position : 68:0 [Time Travel] Exception : Exception of type Hardware at PC: 0X540020Klicka på fältet Undantag för att ytterligare öka detaljnivån för undantagsdata.
0:000> dx -r1 @$curprocess.TTD.Events[17].Exception @$curprocess.TTD.Events[17].Exception : Exception of type Hardware at PC: 0X540020 Position : 68:0 [Time Travel] Type : Hardware ProgramCounter : 0x540020 Code : 0xc0000005 Flags : 0x0 RecordAddress : 0x0Undantagsdata anger att detta är ett maskinvarufel som genereras av processorn. Den innehåller också undantagskoden för 0xc0000005 som anger att detta är en åtkomstöverträdelse. Detta indikerar vanligtvis att vi försökte skriva till minnet som vi inte har åtkomst till.
Klicka på länken [Tidsresa] i undantagshändelsen för att flytta till den positionen i spårningen.
0:000> dx @$curprocess.TTD.Events[17].Exception.Position.SeekTo() Setting position: 68:0 @$curprocess.TTD.Events[17].Exception.Position.SeekTo() (16c8.1f28): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 68:0 eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c ebp=00520055 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 00540020 ??Observera i det här utdata att stacken och baspekaren pekar på två mycket olika adresser.
esp=00effe4c ebp=00520055Detta kan tyda på stackkorruption – möjligen att en funktion returnerades och sedan skadade stacken. För att verifiera detta måste vi gå tillbaka till innan cpu-tillståndet skadades och se om vi kan avgöra när stacken skadades.
Granska de lokala variablerna och ange en kodbrytningspunkt
Vid tidpunkten för spårningsfel är det vanligt att sluta med några steg efter den verkliga orsaken till felhanteringskoden. Med tidsresor kan vi gå tillbaka en instruktion i taget för att hitta den verkliga orsaken.
I menyfliksområdet Start använder du kommandot Step Into Back för att gå tillbaka tre instruktioner. När du gör detta fortsätter du att undersöka stack- och minnesfönstren.
Kommandofönstret visar tidsresepositionen och registreringarna när du går tillbaka tre instruktioner.
0:000> t- Time Travel Position: 67:40 eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c ebp=00520055 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 00540020 ?? ??? 0:000> t- Time Travel Position: 67:3F eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=0019193d esp=00effe48 ebp=00520055 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 DisplayGreeting!main+0x4d: 0019193d c3 0:000> t- Time Travel Position: 67:39 eax=0000004c ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00191935 esp=00effd94 ebp=00effe44 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 DisplayGreeting!main+0x45:Anmärkning
I den här genomgången visar kommandoutdata de kommandon som kan användas i stället för menyalternativen för användargränssnittet så att användare med en kommandoradsanvändningsinställning kan använda kommandoradskommandon.
Vid den här tidpunkten i spårningen har vår stack och baspekare värden som är mer meningsfulla, så det verkar som om vi har kommit närmare punkten i koden där skadan inträffade.
esp=00effd94 ebp=00effe44Det är också intressant att det lokala fönstret innehåller värden från vår målapp och att källkodsfönstret markerar den kodrad som är redo att köras nu i spårningen.
För ytterligare undersökning kan vi öppna ett minnesfönster för att visa innehållet nära minnesadressen för baspekaren för 0x00effe44.
Om du vill visa de associerade ASCII-tecknen går du till menyfliksområdet Minne och väljer Text och sedan ASCII.
I stället för att baspekaren pekar på en instruktion pekar den på vår meddelandetext. Så något är fel här, detta kan vara nära den tidpunkt då vi kan ha skadat stacken. För ytterligare undersökning anger vi en brytpunkt.
Anmärkning
I det här mycket lilla exemplet skulle det vara ganska enkelt att bara titta i koden, men om det finns hundratals rader med kod och dussintals subrutiner kan de tekniker som beskrivs här användas för att minska den tid som krävs för att hitta problemet.
TTD och brytpunkter
Att använda brytpunkter är en vanlig metod för att pausa kodexekvering vid någon händelse av intresse. Med TTD kan du ange en brytpunkt och resa tillbaka i tiden tills brytpunkten nås efter att spårningen har registrerats. Möjligheten att undersöka processtillståndet när ett problem har inträffat, för att fastställa den bästa platsen för en brytpunkt, möjliggör ytterligare felsökningsarbetsflöden som är unika för TTD.
Brytpunkter för minnesåtkomst
Du kan ange brytpunkter som utlöses när en minnesplats används. Använd kommandot ba (break on access) med följande syntax.
ba <access> <size> <address> {options}
| Alternativ | Beskrivning |
|---|---|
| e | execute (när CPU hämtar en instruktion från adressen) |
| r | läs/skriv (när en CPU läser eller skriver till adressen) |
| w | skriv (när processorn skriver till adressen) |
Observera att du bara kan ange fyra data brytpunkter vid en viss tidpunkt och det är upp till dig att se till att du justerar dina data korrekt eller att du inte utlöser brytpunkten (ord måste sluta i adresser som är delbara med 2, dwords måste vara delbara med 4 och fyrord med 0 eller 8).
Ange brytpunkten för minnesåtkomst för baspekaren
Nu i spårningen vill vi ange en brytpunkt för skrivminnesåtkomst till baspekaren – ebp som i vårt exempel är 00effe44. För att göra detta använder du ba-kommandot med den adress som vi vill övervaka. Vi vill övervaka skrivoperationer för fyra byte, så vi specificerar w4.
0:000> ba w4 00effe44Välj Visa och sedan Brytpunkter för att bekräfta att de har angetts som avsedda.
På menyn Start väljer du Gå tillbaka för att resa tillbaka i tiden tills brytpunkten har nåtts.
0:000> g- Breakpoint 0 hit Time Travel Position: 5B:92 eax=0000000f ebx=003db000 ecx=00000000 edx=00cc1a6c esi=00d41046 edi=0053fde8 eip=00d4174a esp=0053fcf8 ebp=0053fde8 iopl=0 nv up ei pl nz ac pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216 DisplayGreeting!DisplayGreeting+0x3a: 00d4174a c745e000000000 mov dword ptr [ebp-20h],0 ss:002b:0053fdc8=ccccccccVälj Visa och sedan Lokal. I det lokala fönstret kan vi se att målvariabeln bara har en del av meddelandet, medan källan innehåller all text. Den här informationen stöder idén att stacken har blivit skadad.
Nu kan vi undersöka programstacken för att se vilken kod som är aktiv. Välj Stack i menyfliksområdet Visa.
Eftersom det är mycket osannolikt att funktionen wscpy_s() som tillhandahålls av Microsoft skulle ha ett kodfel som detta, undersöker vi stacken närmare. Stacken visar att Greeting!main anropar Greeting!GetCppConGreeting. I vårt mycket lilla kodexempel kan vi bara öppna koden just nu och förmodligen hitta felet ganska enkelt. Men för att illustrera de tekniker som kan användas med större, mer komplexa program, kommer vi att ange en ny brytpunkt för att undersöka ytterligare.
Ställ in en åtkomstbrytpunkt för funktionen GetCppConGreeting
Använd brytpunktsfönstret för att rensa den befintliga brytpunkten genom att högerklicka på den befintliga brytpunkten och välja Ta bort.
Fastställa adressen till DisplayGreeting!GetCppConGreeting-funktionen med hjälp av dx-kommandot.
0:000> dx &DisplayGreeting!GetCppConGreeting &DisplayGreeting!GetCppConGreeting : 0xb61720 [Type: void (__cdecl*)(wchar_t *,unsigned int)] [Type: void __cdecl(wchar_t *,unsigned int)]Använd ba-kommandot för att ange en brytpunkt för minnesåtkomst. Eftersom funktionen bara kommer att läsas från minnet för körning måste vi ange en r - läs brytpunkt.
0:000> ba r4 b61720Bekräfta att en brytpunkt för maskinvaruläsning är aktiv i brytpunktsfönstret.
Eftersom vi undrar över storleken på hälsningssträngen ställer vi in ett klockfönster för att visa värdet för sizeof(greeting). I menyfliksområdet Visa väljer du Titta och anger storlek(hälsning). Om värdet inte finns i omfånget visas övervakningsfönstret – Det går inte att binda namnet "hälsning".
På menyn Tidsresa använder du Tidsresa för att starta eller använd
!tt 0kommandot för att gå till början av spåret.0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000På startmenyn väljer du Gå eller använder
gkommandot för att gå vidare i koden tills brytpunkten har nåtts.0:000> g Breakpoint 2 hit Time Travel Position: 4B:1AD eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61721 esp=00ddf7a4 ebp=00ddf864 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!GetCppConGreeting+0x1: 00b61721 8bec mov ebp,espPå startmenyn väljer du Stega tillbaka eller använder
g-ukommandot för att backa upp ett steg.0:000> g-u Time Travel Position: 4B:1AA eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61917 esp=00ddf7ac ebp=00ddf864 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!main+0x27: 00b61917 e8def7ffff call DisplayGreeting!ILT+245(?GetCppConGreetingYAXPA_WIZ) (00b610fa)Det verkar som om vi har hittat grundorsaken. Hälsningsmatrisen som vi deklarerade är 50 tecken lång, medan storleken på (hälsningen) som vi skickar till GetCppConGreeting är 0x64, 100.
När vi tittar närmare på storleksproblemet ser vi också att meddelandet är 75 tecken långt och är 76 när du inkluderar slutet av strängtecknet.
HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL DEBUGGING!Ett sätt att åtgärda koden är att utöka storleken på teckenmatrisen till 100.
std::array <wchar_t, 100> greeting{};Och vi måste också ändra sizeof(greeting) till size(greeting) i den här kodraden.
GetCppConGreeting(greeting.data(), size(greeting));För att verifiera dessa korrigeringar kan vi kompilera om koden och bekräfta att den körs utan fel.
Ange en brytpunkt med hjälp av källfönstret
Ett annat sätt att utföra den här undersökningen är att ange en brytpunkt genom att klicka på valfri kodrad. Om du till exempel klickar på höger sida av definitionsraden std:array i källfönstret anges en brytpunkt där.
På menyn Tidsresa använder du kommandot Tidsresa för att starta för att gå till början av spårningen.
0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000I menyfliksområdet Start klickar du på Gå för att gå tillbaka tills du når brytpunkten.
Breakpoint 0 hit Time Travel Position: 5B:AF eax=0000000f ebx=00c20000 ecx=00000000 edx=00000000 esi=013a1046 edi=00effa60 eip=013a17c1 esp=00eff970 ebp=00effa60 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!DisplayGreeting+0x41: 013a17c1 8bf4 mov esi,esp
Ange brytpunkten för åtkomstbrytpunkten för hälsningsvariabeln
Ett annat alternativt sätt att utföra den här undersökningen är att ange en brytpunkt för misstänkta variabler och undersöka vilken kod som ändrar dem. Om du till exempel vill ange en brytpunkt för hälsningsvariabeln i metoden GetCppConGreeting använder du den här proceduren.
Den här delen av genomgången förutsätter att du fortfarande finns vid brytpunkten från föregående avsnitt.
Från Visa och sedan Lokaler. I det lokala fönstret är hälsning tillgänglig i den aktuella kontexten, så vi kommer att kunna fastställa dess minnesplats.
Använd dx-kommandot för att undersöka hälsningsmatrisen.
0:000> dx &greeting &greeting : ddf800 : { size=50 } [Type: std::array<wchar_t,50> *] [<Raw View>] [Type: std::array<wchar_t,50>] [0] : 3 [Type: wchar_t] [1] : 0 [Type: wchar_t]I den här spårningen är hälsning placerad i minnet på ddf800.
Använd brytpunktsfönstret för att rensa alla befintliga brytpunkter genom att högerklicka på den befintliga brytpunkten och välja Ta bort.
Ange brytpunkten med ba-kommandot med den minnesadress som vi vill övervaka för skrivåtkomst.
ba w4 ddf800På menyn Tidsresa använder du kommandot Tidsresa för att starta för att gå till början av spårningen.
0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000På startmenyn väljer du Gå för att gå vidare till den första minnesåtkomstpunkten för hälsningsmatrisen.
0:000> g- Breakpoint 0 hit Time Travel Position: 5B:9C eax=cccccccc ebx=002b1000 ecx=00000000 edx=68d51a6c esi=013a1046 edi=001bf7d8 eip=013a1735 esp=001bf6b8 ebp=001bf7d8 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!GetCppConGreeting+0x25: 013a1735 c745ec04000000 mov dword ptr [ebp-14h],4 ss:002b:001bf7c4=ccccccccAlternativt kunde vi ha rest till slutet av spåret och arbetat baklänges genom koden för att hitta den sista punkten i spåret som minnesplatsen för arrayen skrevs till.
Använd TTD. Minnesobjekt för att visa minnesåtkomst
Ett annat sätt att avgöra vid vilka punkter i spårningsminnet som har använts är att använda TTD.Memory-objekt och dx-kommandot.
Använd dx-kommandot för att undersöka hälsningsmatrisen.
0:000> dx &greeting &greeting : 0xddf800 [Type: std::array<wchar_t,50> *] [+0x000] _Elems : "꽘棶檙瞝???" [Type: wchar_t [50]]I det här spåret finns hälsningen i minnet på ddf800.
Använd dx-kommandot för att titta på de fyra byte i minnet som börjar på den adressen med läsbehörighet.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw") @$cursession.TTD.Memory(0x1bf7d0,0x1bf7d4, "rw") [0x0] [0x1] [0x2] [0x3] [0x4] [0x5] [0x6] [0x7] [0x8] [0x9] [0xa] ...Klicka på någon av förekomsterna för att visa mer information om den förekomsten av minnesåtkomst.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5] @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5] EventType : MemoryAccess ThreadId : 0x710 UniqueThreadId : 0x2 TimeStart : 27:3C1 [Time Travel] TimeEnd : 27:3C1 [Time Travel] AccessType : Write IP : 0x6900432f Address : 0xddf800 Size : 0x4 Value : 0xddf818 OverwrittenValue : 0x0 SystemTimeStart : Monday, November 18, 2024 23:01:43.400 SystemTimeEnd : Monday, November 18, 2024 23:01:43.400Klicka på [Tidsresa] så att TimeStart kan placera spåret vid tidpunkten.
0:000> dx @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 27:3C1 eax=00ddf81c ebx=00fa2000 ecx=00ddf818 edx=ffffffff esi=00000000 edi=00b61046 eip=6900432f esp=00ddf804 ebp=00ddf810 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 ucrtbased!_register_onexit_function+0xf: 6900432f 51 push ecxOm vi är intresserade av den senaste förekomsten av minnesåtkomst för läsning/skrivning i spårningen kan vi klicka på det sista objektet i listan eller lägga till . Funktionen Last() till slutet av dx-kommandot.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw").Last() @$cursession.TTD.Memory(0xddf800,0xddf804, "rw").Last() EventType : MemoryAccess ThreadId : 0x710 UniqueThreadId : 0x2 TimeStart : 53:100E [Time Travel] TimeEnd : 53:100E [Time Travel] AccessType : Read IP : 0x690338e4 Address : 0xddf802 Size : 0x2 Value : 0x45 SystemTimeStart : Monday, November 18, 2024 23:01:43.859 SystemTimeEnd : Monday, November 18, 2024 23:01:43.859Vi skulle kunna klicka på [Tidsresa] för att flytta till den positionen i spårningen och granska kodkörningen närmare vid den tidpunkten, med hjälp av de tekniker som beskrivs tidigare i den här övningen.
Mer information om TTD. Minnesobjekt, se TTD. Minnesobjekt.
Sammanfattning
I det här mycket lilla exemplet kunde problemet ha fastställts genom att titta på de få kodraderna, men i större program kan de tekniker som presenteras här användas för att minska den tid som krävs för att hitta ett problem.
När en spårning har registrerats kan spårnings- och återgivningsstegen delas och problemet kan återskapas på valfri dator.
Se även
Felsökning av tidsresande – Översikt
Felsökning av tidsresor – inspelning