Condividi tramite


Introduzione agli oggetti debug di viaggi temporali

Logo di debug del tempo di viaggio con un orologio.

Questa sezione descrive come usare il modello di dati per eseguire query sulle tracce di spostamento temporali. Questo può essere uno strumento potente per rispondere a domande come queste sul codice acquisito in una traccia di viaggio temporale.

  • Quali eccezioni si trovano nella traccia?
  • In quale momento della traccia è stato caricato un modulo di codice specifico?
  • Quando sono stati creati/terminati thread nella traccia?
  • Quali sono i thread con esecuzione più lunga nella traccia?

Sono disponibili estensioni TTD che aggiungono dati agli oggetti modello di dati Session e Process . È possibile accedere agli oggetti modello di dati TTD tramite il comando dx (Display Debugger Object Model Expression), le finestre dei modelli di WinDbg, JavaScript e C++. Le estensioni TTD vengono caricate automaticamente durante il debug di una traccia di viaggio temporale.

Elaborare oggetti

Gli oggetti primari aggiunti agli oggetti Process sono disponibili nello spazio dei nomi TTD di qualsiasi oggetto Process . Ad esempio: @$curprocess.TTD.

:000> dx @$curprocess.TTD
@$curprocess.TTD                
    Threads         
    Events          
    Lifetime         : [26:0, 464232:0]
    SetPosition      [Sets the debugger to point to the given position on this process.]

Per informazioni generali sull'uso di query LINQ e oggetti debugger, vedere Uso di LINQ Con gli oggetti debugger.

Proprietà

Oggetto Descrizione
Durata Oggetto intervallo TTD che descrive la durata dell'intera traccia.
Threads Contiene una raccolta di oggetti thread TTD, uno per ogni thread per tutta la durata della traccia.
evento Contiene una raccolta di oggetti evento TTD, uno per ogni evento nella traccia.

Metodi

metodo Descrizione
SetPosition() Accetta un numero intero compreso tra 0 e 100 o stringa nel formato N:N come input e passa la traccia a tale posizione. Per altre informazioni, vedere !tt .

Oggetti sessione

Gli oggetti primari aggiunti agli oggetti Session sono disponibili nello spazio dei nomi TTD all'esterno di qualsiasi oggetto Session. Ad esempio: @$cursession.TTD.

0:000> dx @$cursession.TTD
@$cursession.TTD                 : [object Object]
    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"])]
    DefaultParameterCount : 0x4
    AsyncQueryEnabled : false
    Resources       
    Data             : Normalized data sources based on the contents of the time travel trace
    Utility          : Methods that can be useful when analyzing time travel traces

Nota

Esistono alcuni oggetti e metodi aggiunti da TTDAnalyze che vengono usati per le funzioni interne dell'estensione. Non tutti gli spazi dei nomi sono documentati e gli spazi dei nomi correnti si evolveranno nel tempo.

Metodi

metodo Descrizione
Data.Heap() Raccolta di oggetti heap allocati durante la traccia. Si noti che si tratta di una funzione che esegue il calcolo, quindi è necessario un po' di tempo per l'esecuzione.
Chiamate() Restituisce una raccolta di chiamate di oggetti che corrispondono alla stringa di input. La stringa di input può contenere caratteri jolly. Si noti che si tratta di una funzione che esegue il calcolo, quindi è necessario un po' di tempo per l'esecuzione.
Memory() Si tratta di un metodo che accetta parametri beginAddress, endAddress e dataAccessMask e restituisce una raccolta di oggetti memoria. Si noti che si tratta di una funzione che esegue il calcolo, quindi è necessario un po' di tempo per l'esecuzione.

Ordinamento dell'output della query

Utilizzare il metodo OrderBy() per ordinare le righe restituite dalla query in base a una o più colonne. In questo esempio viene ordinato in base a TimeStart in ordine crescente.

0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)
@$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)                
    [0xb]           
        EventType        : Call
        ThreadId         : 0x3a10
        UniqueThreadId   : 0x2
        TimeStart        : 39:2DC [Time Travel]
        TimeEnd          : 39:2DF [Time Travel]
        Function         : UnknownOrMissingSymbols
        FunctionAddress  : 0x7561ccc0
        ReturnAddress    : 0x7593d24c
        ReturnValue      : 0x0
        Parameters      
    [0xe]           
        EventType        : Call
        ThreadId         : 0x3a10
        UniqueThreadId   : 0x2
        TimeStart        : AF:36 [Time Travel]
        TimeEnd          : AF:39 [Time Travel]
        Function         : UnknownOrMissingSymbols
        FunctionAddress  : 0x7561ccc0
        ReturnAddress    : 0x4723ef
        ReturnValue      : 0x0
        Parameters  

Per visualizzare una profondità aggiuntiva degli oggetti del modello di dati, viene usata l'opzione -r2 a livello di ricorsione. Per altre informazioni sulle opzioni del comando dx, vedere dx (Display Debugger Object Model Expression).

In questo esempio viene ordinato in base a TimeStart in ordine decrescente.

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    

Specifica di elementi in una query

Per selezionare un elemento specifico, è possibile aggiungere alla query un'ampia gamma di qualificatori. Ad esempio, la query visualizza la prima chiamata che contiene "kernelbase! GetLastError".

0:000> dx @$cursession.TTD.Calls("kernelbase!GetLastError").First()
@$cursession.TTD.Calls("kernelbase!GetLastError").First()                
    EventType        : Call
    ThreadId         : 0x3a10
    UniqueThreadId   : 0x2
    TimeStart        : 77A:9 [Time Travel]
    TimeEnd          : 77A:C [Time Travel]
    Function         : UnknownOrMissingSymbols
    FunctionAddress  : 0x7561ccc0
    ReturnAddress    : 0x6cf12406
    ReturnValue      : 0x0
    Parameters    

Applicazione di filtri in una query

Utilizzare il metodo Select() per scegliere le colonne da visualizzare e modificare il nome visualizzato della colonna.

Questo esempio restituisce righe in cui ReturnValue non è zero e seleziona per visualizzare le colonne TimeStart e ReturnValue con nomi visualizzati personalizzati di Time and 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 })                
    [0x13]          
        Time             : 3C64A:834 [Time Travel]
        Error            : 0x36b7
    [0x1c]          
        Time             : 3B3E7:D6 [Time Travel]
        Error            : 0x3f0
    [0x1d]          
        Time             : 3C666:857 [Time Travel]
        Error            : 0x36b7
    [0x20]          
        Time             : 3C67E:12D [Time Travel]

Raggruppamento

Utilizzare il metodo GroupBy() per raggruppare i dati restituiti dalla query per eseguire l'analisi usando risultati strutturati Questo esempio raggruppa le posizioni temporali in base al numero di errore.

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]           
...

Assegnazione del risultato di una query a una variabile

Usare questa sintassi per assegnare il risultato di una query a una variabile dx @$var = <expression>

In questo esempio vengono assegnati i risultati di una query a myResults

dx -r2 @$myResults = @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })

Usare il comando dx per visualizzare la variabile appena creata usando l'opzione griglia -g. Per altre informazioni sulle opzioni del comando dx, vedere 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     =

Esempi

Esecuzione di query per le eccezioni

Questa query LINQ usa il TTD. Oggetto evento per visualizzare tutte le eccezioni nella traccia.

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

Esecuzione di query per chiamate API specifiche

Usare TTD. Chiama l'oggetto per eseguire una query per chiamate API specifiche. In questo esempio si è verificato un errore quando si chiama user32! MessageBoxW, l'API Di Windows per visualizzare una finestra di messaggio. Vengono elencate tutte le chiamate a MessageBoxW , ordinarlo in base all'ora di inizio della funzione e quindi selezionare l'ultima chiamata.

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

Esecuzione di query per l'evento di caricamento di un modulo specifico

Usare prima di tutto il comando lm (Elenca moduli caricati) per visualizzare i moduli caricati.

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)

Usare quindi il comando dx seguente per vedere in quale posizione nella traccia è stato caricato un modulo specifico, ad esempio 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 

Questa query LINQ visualizza gli eventi di caricamento di un modulo specifico.

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

L'indirizzo di FFFFFFFFFFFFFE:0 indica la fine della traccia.

Esecuzione di query per tutti i controlli degli errori nella traccia

Usare questo comando per ordinare in base a tutti i controlli degli errori nella traccia in base al numero di errori.

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        =

Esecuzione di query sulla posizione temporale nella traccia durante la creazione di thread

Usare questo comando dx per visualizzare tutti gli eventi nella traccia in formato griglia (-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... -                        =
==================================================================================================================================================================================================

Selezionare una delle colonne con un segno + per ordinare l'output.

Usare questa query LINQ per visualizzare in formato griglia, la posizione temporale nella traccia al momento della creazione dei thread (tipo == "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]    =
===========================================================================================================

Usare questa query LINQ per visualizzare in formato griglia le posizioni temporali nella traccia quando i thread sono stati terminati (tipo == "ThreadTerminati").

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]    =
===========================================================================================================

Ordinamento dell'output per determinare i thread con esecuzione più lunga

Usare questa query LINQ per visualizzare in formato griglia, i thread con esecuzione più lunga approssimativi nella traccia.

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            =
=========================================================

Esecuzione di query per l'accesso in lettura a un intervallo di memoria

Usare il TTD. Oggetto Memoria su cui eseguire una query per eseguire una query per l'accesso in lettura a un intervallo di memoria.

Thread Environment Block (TEB) è una struttura che contiene tutte le informazioni relative allo stato di un thread, incluso il risultato restituito da GetLastError(). È possibile eseguire una query su questa struttura di dati eseguendo dx @$teb per il thread corrente. Uno dei membri di TEB è una variabile LastErrorValue, di 4 byte. È possibile fare riferimento al membro LastErrorValue nel TEB usando questa sintassi. dx &@$teb->LastErrorValue.

La query di esempio mostra come trovare tutte le operazioni di lettura eseguite in tale intervallo in memoria, selezionare tutte le letture che si verificano prima della creazione di una finestra di dialogo e quindi ordinare il risultato per trovare l'ultima operazione di lettura.

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]     

Se nella traccia è stato eseguito un evento "dialog" è possibile eseguire una query per trovare tutte le operazioni di lettura eseguite in tale intervallo in memoria, selezionare tutte le letture che si verificano prima della creazione della finestra di dialogo e quindi ordinare il risultato per trovare l'ultima operazione di lettura. Quindi il viaggio temporale a quel punto nel tempo chiamando SeekTo() sulla posizione temporale risultante.


: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

Per un'esercitazione su come eseguire il debug del codice C++ usando una registrazione del debug di viaggi temporali tramite query per trovare informazioni sull'esecuzione del codice problematico in questione, vedere https://github.com/Microsoft/WinDbg-Samples/blob/master/TTDQueries/tutorial-instructions.md.

Tutto il codice usato nel lab è disponibile qui: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.

Risoluzione dei problemi relativi alle query TTD

"UnknownOrMissingSymbols" come nomi di funzione

L'estensione del modello di dati richiede informazioni complete sui simboli per fornire nomi di funzione, valori dei parametri e così via. Quando le informazioni complete sui simboli non sono disponibili, il debugger usa "UnknownOrMissingSymbols" come nome della funzione.

  • Se si dispone di simboli privati, si otterrà il nome della funzione e l'elenco corretto di parametri.
  • Se si dispone di simboli pubblici, si otterranno il nome della funzione e un set predefinito di parametri , quattro int senza segno a 64 bit.
  • Se non si dispone di informazioni sui simboli per il modulo su cui si sta eseguendo una query, viene usato "UnknownOrMissingSymbols" come nome.

Query TTD per le chiamate

Esistono diversi motivi per cui una query non restituisce nulla per le chiamate a una DLL.

  • La sintassi per la chiamata non è corretta. Provare a verificare la sintassi della chiamata usando il comando x: "x <call>". Se il nome del modulo restituito da x è in lettere maiuscole, usarlo.
  • La DLL non è ancora caricata e viene caricata in un secondo momento nella traccia. Per aggirare questo viaggio fino a un punto nel tempo dopo il caricamento della DLL e il rollforward della query.
  • La chiamata è inlined che il motore di query non è in grado di tenere traccia.
  • Il modello di query usa caratteri jolly che restituiscono troppe funzioni. Provare a rendere il modello di query più specifico in modo che il numero di funzioni corrispondenti sia sufficientemente piccolo.

Vedi anche

Uso di LINQ Con gli oggetti debugger

dx (Display Debugger Object Model Expression)

Debug di viaggi temporali - Panoramica

Debug di viaggi temporali - Automazione JavaScript