Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tato část popisuje, jak pomocí datového modelu dotazovat časové stopy cestování. Může to být užitečný nástroj pro zodpovězení otázek, jako jsou ty, které se týkají kódu zachyceného v trasování časového cestování.
- Jaké výjimky jsou v záznamu trasování?
- V jakém okamžiku se v trasování nahrál konkrétní modul kódu?
- Kdy bylo vlákno vytvořeno nebo ukončeno v záznamu?
- Jaké jsou nejdéle běžící vlákna v trasování?
Existují rozšíření TTD, která přidávají data do relace a procesu objekty datového modelu. Objekty datového modelu TTD jsou přístupné prostřednictvím příkazu dx (Display Debugger Object Model Expression), windows modelu WinDbg, JavaScript a C++. Rozšíření TTD se automaticky načítají při ladění časové stopy.
Procesní objekty
Primární objekty přidané do Process objektů lze najít v oboru názvů TTD v rámci jakéhokoli objektu Process. Například @$curprocess.TTD.
0:000> dx @$curprocess.TTD
@$curprocess.TTD
Index
Threads
Events
DebugOutput
Lifetime : [2C8:0, 16EC:98A]
DefaultMemoryPolicy : InFragmentAggressive
SetPosition [Sets the debugger to point to the given position on this process.]
GatherMemoryUse [0]
RecordClients
PrevMemoryAccess [(accessMask, address, size [, address, size, ...]) - Find the previous matching memory access before current position.]
NextMemoryAccess [(accessMask, address, size [, address, size, ...]) - Find the next matching memory access after current position.]
Recorder
Obecné informace o práci s dotazy LINQ a objekty ladicího programu naleznete v tématu Použití LINQ S objekty ladicího programu.
Vlastnosti
| Objekt | Popis |
|---|---|
| Životnost | Objekt oblasti TTD popisující životnost celého trasování. |
| Vlákna | Obsahuje kolekci objektů vlákna TTD, jeden pro každé vlákno po celou dobu životnosti trasování. |
| Události | Obsahuje kolekci objektů událostí TTD, jeden pro každou událost ve sledu. |
Metody
| Metoda | Popis |
|---|---|
| SetPosition() | Vezme celé číslo v rozsahu 0 až 100 nebo řetězec ve formátu N:N jako vstup a přeskočí trasování do daného umístění. Další informace najdete na !tt. |
Objekty relace
Primární objekty přidané do objektů Session lze najít v oboru názvů TTD od jakéhokoli objektu Session. Například @$cursession.TTD.
0:000> dx @$cursession.TTD
@$cursession.TTD
Calls [Returns call information from the trace for the specified set of methods: TTD.Calls("module!method1", "module!method2", ...) For example: dx @$cursession.TTD.Calls("user32!SendMessageA")]
Memory [Returns memory access information for specified address range: TTD.Memory(startAddress, endAddress [, "rwec"])]
MemoryForPositionRange [Returns memory access information for specified address range and position range: TTD.MemoryForPositionRange(startAddress, endAddress [, "rwec"], minPosition, maxPosition)]
PinObjectPosition [Pins an object to the given time position: TTD.PinObjectPosition(obj, pos)]
AsyncQueryEnabled : false
RichQueryTypesEnabled : true
DefaultParameterCount : 0x4
Data : Normalized data sources based on the contents of the time travel trace
Utility : Methods that can be useful when analyzing time travel traces
Analyzers : Methods that perform code analysis on the time travel trace
Bookmarks : Bookmark collection
Checkers : Checkers (scripts for detection of common issues recorded in a time travel trace)
Poznámka:
Existují některé objekty a metody přidané TTDAnalyze, které se používají pro interní funkce rozšíření. Ne všechny obory názvů jsou zdokumentované a aktuální obory názvů se budou v průběhu času vyvíjet.
Metody
| Metoda | Popis |
|---|---|
| Data.Heap() | Kolekce objektů haldy, které byly přiděleny během trasování. Všimněte si, že se jedná o funkci, která provádí výpočty, takže spuštění nějakou dobu trvá. |
| Calls() | Vrátí kolekci objektů volání, které odpovídají vstupnímu řetězci. Vstupní řetězec může obsahovat zástupné znaky. Všimněte si, že se jedná o funkci, která provádí výpočty, takže spuštění nějakou dobu trvá. |
| Memory() | Jedná se o metodu, která přebírá parametry beginAddress, endAddress a dataAccessMask a vrací kolekci paměťových objektů. Všimněte si, že se jedná o funkci, která provádí výpočty, takže spuštění nějakou dobu trvá. |
Řazení výstupu dotazu
Pomocí metody OrderBy() seřaďte řádky vrácené z dotazu podle jednoho nebo více sloupců. Tento příklad seřadí podle TimeStart ve vzestupném pořadí.
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)
@$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)
[0x0]
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 718:7D7 [Time Travel]
TimeEnd : 718:7DA [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff99855ac5a
ReturnValue : 0x0 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
[0x1]
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 72D:1B3 [Time Travel]
TimeEnd : 72D:1B6 [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff9961538df
ReturnValue : 0x57 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
...
K zobrazení další hloubky objektů datového modelu se používá možnost -r2 rekurzní úroveň. Další informace o možnostech příkazu dx naleznete v tématu dx (Display Debugger Object Model Expression).
Tento příklad seřadí podle TimeStartu v sestupném pořadí.
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").OrderByDescending(c => c.TimeStart)
@$cursession.TTD.Calls("kernelbase!GetLastError").OrderByDescending(c => c.TimeStart)
[0x1896]
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 464224:34 [Time Travel]
TimeEnd : 464224:37 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x7561ccc0
ReturnAddress : 0x7594781c
ReturnValue : 0x0
Parameters
[0x18a0]
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 464223:21 [Time Travel]
TimeEnd : 464223:24 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x7561ccc0
ReturnAddress : 0x7594781c
ReturnValue : 0x0
Parameters
Určení prvků v dotazu
Pokud chcete vybrat konkrétní prvek, můžete k dotazu připojit řadu kvalifikátorů. Dotaz například zobrazí první volání, které obsahuje "kernelbase!GetLastError".
0:000> dx @$cursession.TTD.Calls("kernelbase!GetLastError").First()
@$cursession.TTD.Calls("kernelbase!GetLastError").First()
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 718:7D7 [Time Travel]
TimeEnd : 718:7DA [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff99855ac5a
ReturnValue : 0x0 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
Filtrování v dotazu
Pomocí metody Select() vyberte sloupce, které chcete zobrazit a upravit zobrazovaný název sloupce.
Tento příklad vrátí řádky, kde ReturnValue není nula a vybere zobrazení sloupců TimeStart a ReturnValue s vlastními zobrazovanými názvy Time a Error.
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
@$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
[0x1]
Time : 72D:1B3 [Time Travel]
Error : 0x57 [Type: unsigned long]
[0x2]
Time : 72D:1FC [Time Travel]
Error : 0x2af9 [Type: unsigned long]
[0x3]
Time : 72D:26E [Time Travel]
Error : 0x2af9 [Type: unsigned long]
Seskupení
Pomocí metody GroupBy() seskupte data vrácená dotazem k provedení analýzy pomocí strukturovaných výsledků. Tento příklad seskupí časová umístění podle čísla chyby.
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue }).GroupBy(x => x.Error)
@$s = @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue }).GroupBy(x => x.Error)
[0x36b7]
[0x0]
[0x1]
[0x2]
[0x3]
[...]
[0x3f0]
[0x0]
[0x1]
[0x2]
[0x3]
...
Přiřazení výsledku dotazu k proměnné
Tato syntaxe slouží k přiřazení výsledku dotazu k proměnné dx @$var = <expression>
Tento příklad přiřadí výsledky dotazu myResults.
dx -r2 @$myResults = @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
Pomocí příkazu dx zobrazte nově vytvořenou proměnnou pomocí možnosti -g mřížky. Další informace o možnostech příkazu dx naleznete v tématu dx (Display Debugger Object Model Expression).
0:000> dx -g @$myResults
========================================
= = (+) Time = (+) Error =
========================================
= [0x13] - 3C64A:834 - 0x36b7 =
= [0x1c] - 3B3E7:D6 - 0x3f0 =
= [0x1d] - 3C666:857 - 0x36b7 =
= [0x20] - 3C67E:12D - 0x2 =
= [0x21] - 3C6F1:127 - 0x2 =
= [0x23] - 3A547:D6 - 0x3f0 =
= [0x24] - 3A59B:D0 - 0x3f0 =
Příklady
Dotazování na výjimky
Tento dotaz LINQ používá TTD. Objekt události k zobrazení všech výjimek v trasování.
0:000> dx @$curprocess.TTD.Events.Where(t => t.Type == "Exception").Select(e => e.Exception)
@$curprocess.TTD.Events.Where(t => t.Type == "Exception").Select(e => e.Exception)
[0x0] : Exception 0x000006BA of type Software at PC: 0X777F51D0
[0x1] : Exception 0x000006BA of type Software at PC: 0X777F51D0
[0x2] : Exception 0xE06D7363 of type CPlusPlus at PC: 0X777F51D0
Dotazování na konkrétní volání rozhraní API
Použijte objekt TTD.Calls pro dotazování na konkrétní volání API. V tomto příkladu došlo k chybě při volání user32! MessageBoxW, rozhraní API systému Windows pro zobrazení pole zprávy. Zobrazíme seznam všech volání MessageBoxW , pořadí podle počátečního času funkce a pak vyberte poslední volání.
0:000> dx @$cursession.TTD.Calls("user32!MessageBoxW").OrderBy(c => c.TimeStart).Last()
@$cursession.TTD.Calls("user32!MessageBoxW").OrderBy(c => c.TimeStart).Last()
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 458310:539 [Time Travel]
TimeEnd : 45C648:61 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x750823a0
ReturnAddress : 0x40cb93
ReturnValue : 0x10a7000000000001
Parameters
Dotazování na událost načítání konkrétního modulu
Nejprve pomocí příkazu lm (List Loaded Modules) zobrazte načtené moduly.
0:000> lm
start end module name
012b0000 012cf000 CDog_Console (deferred)
11570000 1158c000 VCRUNTIME140D (deferred)
11860000 119d1000 ucrtbased (deferred)
119e0000 11b63000 TTDRecordCPU (deferred)
11b70000 11cb1000 TTDWriter (deferred)
73770000 73803000 apphelp (deferred)
73ea0000 74062000 KERNELBASE (deferred)
75900000 759d0000 KERNEL32 (deferred)
77070000 771fe000 ntdll (private pdb symbols)
Pak pomocí následujícího příkazu dx zjistěte, v jaké pozici trasování byl načten konkrétní modul, například ntdll.
dx @$curprocess.TTD.Events.Where(t => t.Type == "ModuleLoaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
@$curprocess.TTD.Events.Where(t => t.Type == "ModuleLoaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
[0x0] : Module Loaded at position: A:0
Tento dotaz LINQ zobrazí události načítání konkrétního modulu.
0:000> dx @$curprocess.TTD.Events.Where(t => t.Type == "ModuleUnloaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
@$curprocess.TTD.Events.Where(t => t.Type == "ModuleUnloaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
[0x0] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0
Adresa FFFFFFFFFFFFFFFE:0 označuje konec trasování.
Dotazování na všechny kontroly chyb v trasování
Použijte tento příkaz k řazení kontrol chyb při trasování podle počtu chyb.
0:000> dx -g @$cursession.TTD.Calls("kernelbase!GetLastError").Where( x=> x.ReturnValue != 0).GroupBy(x => x.ReturnValue).Select(x => new { ErrorNumber = x.First().ReturnValue, ErrorCount = x.Count()}).OrderByDescending(p => p.ErrorCount),d
==================================================
= = (+) ErrorNumber = ErrorCount =
==================================================
= [1008] - 1008 - 8668 =
= [14007] - 14007 - 4304 =
= [2] - 2 - 1710 =
= [6] - 6 - 1151 =
= [1400] - 1400 - 385 =
= [87] - 87 - 383 =
Dotazování na časový okamžik ve stopě, kdy byla vlákna vytvořena
Tento příkaz dx slouží k zobrazení všech událostí v trasování ve formátu mřížky (-g).
0:000> dx -g @$curprocess.TTD.Events
==================================================================================================================================================================================================
= = (+) Type = (+) Position = (+) Module = (+) Thread =
==================================================================================================================================================================================================
= [0x0] : Module Loaded at position: 2:0 - ModuleLoaded - 2:0 - Module C:\Users\USER1\Documents\Visual Studio 2015\Proje... - =
= [0x1] : Module Loaded at position: 3:0 - ModuleLoaded - 3:0 - Module C:\WINDOWS\SYSTEM32\VCRUNTIME140D.dll at address 0... - =
= [0x2] : Module Loaded at position: 4:0 - ModuleLoaded - 4:0 - Module C:\WINDOWS\SYSTEM32\ucrtbased.dll at address 0X118... - =
= [0x3] : Module Loaded at position: 5:0 - ModuleLoaded - 5:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x4] : Module Loaded at position: 6:0 - ModuleLoaded - 6:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x5] : Module Loaded at position: 7:0 - ModuleLoaded - 7:0 - Module C:\WINDOWS\SYSTEM32\apphelp.dll at address 0X73770... - =
= [0x6] : Module Loaded at position: 8:0 - ModuleLoaded - 8:0 - Module C:\WINDOWS\System32\KERNELBASE.dll at address 0X73... - =
= [0x7] : Module Loaded at position: 9:0 - ModuleLoaded - 9:0 - Module C:\WINDOWS\System32\KERNEL32.DLL at address 0X7590... - =
= [0x8] : Module Loaded at position: A:0 - ModuleLoaded - A:0 - Module C:\WINDOWS\SYSTEM32\ntdll.dll at address 0X7707000... - =
= [0x9] : Thread created at D:0 - ThreadCreated - D:0 - - UID: 2, TID: 0x4C2C =
= [0xa] : Thread terminated at 64:0 - ThreadTerminated - 64:0 - - UID: 2, TID: 0x4C2C =
= [0xb] : Thread created at 69:0 - ThreadCreated - 69:0 - - UID: 3, TID: 0x4CFC =
= [0xc] : Thread created at 6A:0 - ThreadCreated - 6A:0 - - UID: 4, TID: 0x27B0 =
= [0xd] : Thread terminated at 89:0 - ThreadTerminated - 89:0 - - UID: 4, TID: 0x27B0 =
= [0xe] : Thread terminated at 8A:0 - ThreadTerminated - 8A:0 - - UID: 3, TID: 0x4CFC =
= [0xf] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\Documents\Visual Studio 2015\Proje... - =
= [0x10] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x11] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\VCRUNTIME140D.dll at address 0... - =
= [0x12] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x13] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\ucrtbased.dll at address 0X118... - =
= [0x14] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\apphelp.dll at address 0X73770... - =
= [0x15] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\System32\KERNELBASE.dll at address 0X73... - =
= [0x16] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\System32\KERNEL32.DLL at address 0X7590... - =
= [0x17] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\ntdll.dll at address 0X7707000... - =
==================================================================================================================================================================================================
Výběrem libovolného sloupce se znaménkem + seřadíte výstup.
Použijte tento dotaz LINQ k zobrazení v mřížkovém formátu, časové pozice v trasovacím záznamu, kdy byly vlákna vytvořena (Type == "ThreadCreated").
dx -g @$curprocess.TTD.Events.Where(t => t.Type == "ThreadCreated").Select(t => t.Thread)
===========================================================================================================
= = (+) UniqueId = (+) Id = (+) Lifetime = (+) ActiveTime =
===========================================================================================================
= [0x0] : UID: 2, TID: 0x4C2C - 0x2 - 0x4c2c - [0:0, FFFFFFFFFFFFFFFE:0] - [D:0, 64:0] =
= [0x1] : UID: 3, TID: 0x4CFC - 0x3 - 0x4cfc - [0:0, 8A:0] - [69:0, 8A:0] =
= [0x2] : UID: 4, TID: 0x27B0 - 0x4 - 0x27b0 - [0:0, 89:0] - [6A:0, 89:0] =
===========================================================================================================
Pomocí tohoto dotazu LINQ můžete zobrazit ve formátu mřížky časové pozice v trasování, kdy byla vlákna ukončena (Typ == "ThreadTerminated").
0:000> dx -g @$curprocess.TTD.Events.Where(t => t.Type == "ThreadTerminated").Select(t => t.Thread)
===========================================================================================================
= = (+) UniqueId = (+) Id = (+) Lifetime = (+) ActiveTime =
===========================================================================================================
= [0x0] : UID: 2, TID: 0x4C2C - 0x2 - 0x4c2c - [0:0, FFFFFFFFFFFFFFFE:0] - [D:0, 64:0] =
= [0x1] : UID: 4, TID: 0x27B0 - 0x4 - 0x27b0 - [0:0, 89:0] - [6A:0, 89:0] =
= [0x2] : UID: 3, TID: 0x4CFC - 0x3 - 0x4cfc - [0:0, 8A:0] - [69:0, 8A:0] =
===========================================================================================================
Řazení výstupu pro určení nejdéle běžících vláken
Tento dotaz LINQ slouží k zobrazení ve formátu mřížky, přibližných nejdéle běžících vláken v trasování.
0:000> dx -g @$curprocess.TTD.Events.Where(e => e.Type == "ThreadTerminated").Select(e => new { Thread = e.Thread, ActiveTimeLength = e.Thread.ActiveTime.MaxPosition.Sequence - e.Thread.ActiveTime.MinPosition.Sequence }).OrderByDescending(t => t.ActiveTimeLength)
=========================================================
= = (+) Thread = ActiveTimeLength =
=========================================================
= [0x0] - UID: 2, TID: 0x1750 - 0x364030 =
= [0x1] - UID: 3, TID: 0x420C - 0x360fd4 =
= [0x2] - UID: 7, TID: 0x352C - 0x35da46 =
= [0x3] - UID: 9, TID: 0x39F4 - 0x34a5b5 =
= [0x4] - UID: 11, TID: 0x4288 - 0x326199 =
= [0x5] - UID: 13, TID: 0x21C8 - 0x2fa8d8 =
= [0x6] - UID: 14, TID: 0x2188 - 0x2a03e3 =
= [0x7] - UID: 15, TID: 0x40E8 - 0x29e7d0 =
= [0x8] - UID: 16, TID: 0x124 - 0x299677 =
= [0x9] - UID: 4, TID: 0x2D74 - 0x250f43 =
= [0xa] - UID: 5, TID: 0x2DC8 - 0x24f921 =
= [0xb] - UID: 6, TID: 0x3B1C - 0x24ec8e =
= [0xc] - UID: 10, TID: 0x3808 - 0xf916f =
= [0xd] - UID: 12, TID: 0x26B8 - 0x1ed3a =
= [0xe] - UID: 17, TID: 0x37D8 - 0xc65 =
= [0xf] - UID: 8, TID: 0x45F8 - 0x1a2 =
=========================================================
Dotazování na přístup pro čtení k rozsahu paměti
Použijte TTD. Objekt paměti dotaz na dotazování na přístup pro čtení k oblasti paměti.
Blok prostředí vlákna (TEB) je struktura, která obsahuje všechny informace týkající se stavu vlákna, včetně výsledku vráceného funkcí GetLastError(). Tuto datovou strukturu můžete dotazovat spuštěním dx @$teb pro aktuální vlákno. Jedním z členů TEB je proměnná LastErrorValue, velikost 4 bajtů. Pomocí této syntaxe můžeme odkazovat na člena LastErrorValue v TEB.
dx &@$teb->LastErrorValue.
Ukázkový dotaz ukazuje, jak najít každou operaci čtení provedenou v této oblasti v paměti, vybrat všechna čtení, ke kterým došlo před vytvořením dialogového okna, a potom seřadit výsledek a najít poslední operaci čtení.
0:000> dx @$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r")
@$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r")
[0x0]
[0x1]
[0x2]
[0x3]
Pokud v našem trasování došlo k události dialogového okna, můžeme spustit dotaz, abychom našli všechny operace čtení provedené v této oblasti v paměti, vyberte všechna čtení, ke kterým dojde před vytvořením dialogového okna, a pak seřaďte výsledek a vyhledejte poslední operaci čtení. Poté, co se přesunete v čase do tohoto bodu, zavolejte funkci SeekTo() na výsledné časové pozici.
:000> dx @$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r").Where(m => m.TimeStart < @$dialog).OrderBy(m => m.TimeStart).Last().TimeEnd.SeekTo()
Setting position: 458300:37
ModLoad: 6cee0000 6cf5b000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 75250000 752e6000 C:\WINDOWS\System32\OLEAUT32.dll
ModLoad: 76320000 7645d000 C:\WINDOWS\System32\MSCTF.dll
ModLoad: 76cc0000 76cce000 C:\WINDOWS\System32\MSASN1.dll
GitHub TTD Query Lab
Kurz, jak ladit C++ kód pomocí nahrávky ladění Time Travel Debugging a využití dotazů pro nalezení informací o provádění problematického kódu, naleznete v tématu WinDbg-Samples - Time Travel Debugging a dotazy.
Veškerý kód použitý v testovacím prostředí je k dispozici zde: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.
Řešení potíží s dotazy TTD
"UnknownOrMissingSymbols" jako názvy funkcí
Rozšíření datového modelu potřebuje úplné informace o symbolech, aby bylo možné zadat názvy funkcí, hodnoty parametrů atd. Pokud nejsou k dispozici úplné informace o symbolech, ladicí program používá jako název funkce "UnknownOrMissingSymbols".
- Pokud máte soukromé symboly, získáte název funkce a správný seznam parametrů.
- Pokud máte veřejné symboly, získáte název funkce a výchozí sadu parametrů – čtyři 64bitové inty bez znaménka.
- Pokud nemáte žádné informace o symbolech pro modul, který dotazujete, použije se jako název "UnknownOrMissingSymbols".
Dotazy TTD pro volání
Může existovat několik důvodů, proč dotaz nic nevrátí při volání na DLL.
- Syntaxe volání není úplně správná. Zkuste ověřit syntaxi volání pomocí x (Prozkoumat symboly)
x <call>. Pokud modul, který vrací x, má název velkými písmeny, použijte ho. - Knihovna DLL ještě není načtena a je načtena později při trasování. Chcete-li tento problém obejít, přesuňte se k určitému bodu v čase po načtení knihovny DLL a dotaz znovu zopakujte.
- Volání je vloženo tak, že jej dotazovací stroj nemůže sledovat.
- Vzor dotazu používá zástupné řady, které vrací příliš mnoho funkcí. Pokuste se, aby byl vzor dotazu konkrétnější, aby byl počet odpovídajících funkcí dostatečně malý.
Viz také
použití LINQ s objekty ladicího programu
dx (zobrazení výrazu objektového modelu ladicího programu)
ladění časových cest – přehled
Ladění časového cestování - automatizace JavaScriptu