Compartilhar via


Introdução à Depuração de objetos de viagem no tempo

Logotipo de depuração da viagem no tempo com um relógio.

Esta seção explica como usar o modelo de dados para consultar rastreamentos de viagem no tempo. Essa pode ser uma ferramenta útil para responder a perguntas como essas sobre o código capturado em um rastreamento de viagem no tempo.

  • Quais são as exceções que estão no rastreamento?
  • Em que ponto do rastreamento um módulo de código específico foi carregado?
  • Em que ponto do rastreamento os threads foram criados/encerrados?
  • Quais são os threads mais longos do rastreamento?

Há extensões TTD que adicionam dados aos objetos de modelo de dados Session e Process. Os objetos de modelo de dados TTD podem ser acessados através do comando dx (Display Debugger Object Model Expression), janelas do modelo WinDbg, JavaScript e C++. As extensões TTD são carregadas automaticamente na depuração de um rastreamento de viagem no tempo.

Processar objetos

Os objetos principais adicionados a objetos Process podem ser encontrados no namespace TTD de qualquer objeto Process. Por exemplo, @$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

Para obter informações gerais sobre como trabalhar com consultas LINQ e objetos do depurador, consulte Usando LINQ com os objetos do depurador.

Propriedades

Objeto Descrição
Vida útil Um objeto de intervalo TTD que descreve o tempo de vida de todo o rastreamento.
Threads Contém uma coleção de objetos de thread TTD, um para cada thread durante toda a vida útil do rastreamento.
Eventos Contém uma coleção de Objetos de evento TTD, um para cada evento no rastreamento.

Métodos

Método Descrição
SetPosition() Pega um inteiro entre 0 e 100 ou uma cadeia de caracteres no formato N:N como entrada e salta o rastreamento para esse local. Consulte !tt para mais informações.

Objetos de sessão

Os objetos principais adicionados a objetos Session podem ser encontrados no namespace TTD de qualquer objeto Session. Por exemplo, @$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)

Observação

Há alguns objetos e métodos adicionados pelo TTDAnalyze que são usados para funções internas da extensão. Nem todos os namespaces são documentados, e os namespaces atuais evoluirão com o tempo.

Métodos

Método Descrição
Data.Heap() Uma coleção de objetos de heap que foram alocados durante o rastreamento. Observe que essa é uma função que faz computação, de modo que leva um tempo para ser executada.
Calls() Retorna uma coleção de objetos de chamadas que correspondem à cadeia de caracteres de entrada. A cadeia de caracteres da entrada pode conter curingas. Observe que essa é uma função que faz computação, de modo que leva um tempo para ser executada.
Memory() Esse é um método que usa os parâmetros beginAddress, endAddress e dataAccessMask e retorna uma coleção de objetos de memória. Observe que essa é uma função que faz computação, de modo que leva um tempo para ser executada.

Como classificar a saída da consulta

Use o método OrderBy() para classificar as linhas que retornarem da consulta por uma ou mais colunas. Este exemplo classifica por TimeStart na ordem crescente.

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

Para mostrar profundidade adicional dos objetos de modelo de dados, é usada a opção de nível de recursão -r2. Para obter mais informações sobre as opções de comando dx, consulte dx (expressão para exibir modelo de objeto de depurador).

Este exemplo classifica por TimeStart na ordem 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    

Como especificar elementos em uma consulta

Para selecionar um elemento específico, diversos qualificadores podem ser anexados à consulta. Por exemplo, a consulta mostra a primeira chamada que contém "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

Como filtrar em uma consulta

Use o método Select() para escolher quais colunas ver e modificar o nome de exibição da coluna.

Este exemplo retorna linhas onde ReturnValue não é zero e seleciona exibir as colunas TimeStart e ReturnValue com nomes de exibição personalizados de Hora e Erro.

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]

Agrupamento

Use o método GroupBy() para agrupar dados retornados pela consulta para executar análises com resultados estruturados. Este exemplo agrupa os locais de hora por número de erro.

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

Como atribuir o resultado de uma consulta a uma variável

Use esta sintaxe para atribuir o resultado de uma consulta a uma variável dx @$var = <expression>

Este exemplo atribui os resultados de uma consulta ao myResults

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

Use o comando dx para ver a variável recém-criada usando a opção de grade -g. Para obter mais informações das opções de comando dx, consulte dx (expressão para exibir modelo de objeto de depurador).

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     =

Exemplos

Consulta para exceções

Esta consulta LINQ usa o objeto TTD.Event para exibir todas as exceções no rastreamento.

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

Consulta para chamadas de API específicas

Use o objeto TTD.Calls para consultar chamadas de API específicas. Neste exemplo, ocorreu um erro ao chamar user32!MessageBoxW, a API do Windows para mostrar uma caixa de mensagem. Listamos todas as chamadas a MessageBoxW, ordenamos pela hora de início da função e, depois, escolhemos a última chamada.

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

Consultar para o evento de carregamento de um módulo específico

Primeiro, use o comando lm (List Loaded Modules) para ver os módulos carregados.

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)

Depois, use o seguinte comando dx para ver em que posição no rastreamento um módulo específico foi carregado, como 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 

Esta consulta LINQ mostra o(s) evento(s) de carregamento de um módulo específico.

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

O endereço de FFFFFFFFFFFFFFFE:0 indica o fim do rastreamento.

Consultar todas as verificações de erro no rastreamento

Use este comando para classificar todas as verificações de erros no rastreamento pela contagem de erros.

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        =

Consultar a posição no tempo no rastreamento quando os threads foram criados

Use este comando dx para mostrar todos os eventos no rastreamento no formato de grade (-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... -                        =
==================================================================================================================================================================================================

Selecione qualquer colunas que tenha um sinal de + para classificar a saída.

Use esta consulta LINQ para ver em formato de grade, a posição no tempo no rastreamento quando os threads foram criados (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]    =
===========================================================================================================

Use esta consulta LINQ para ver em formato de grade, as posições no tempo no rastreamento quando os threads foram encerrados (Type == "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]    =
===========================================================================================================

Classificar a saída para determinar os threads de execução mais longa

Use esta consulta LINQ para exibir, em formato de grade, os threads aproximados de execução mais longa no rastreamento.

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

Consultar acessos de leitura a um intervalo de memória

Use o objeto TTD.Memory para consultar acessos de leitura a um intervalo de memória.

O Bloco de ambiente de thread (TEB) é uma estrutura que contém todas as informações sobre o estado de um thread, incluindo o resultado retornado por GetLastError(). Consulte essa estrutura de dados executando dx @$teb para o thread atual. Um dos membros do TEB é uma variável LastErrorValue, de 4 bytes. Podemos fazer referência ao membro LastErrorValue no TEB com essa sintaxe. dx &@$teb->LastErrorValue.

O exemplo de consulta mostra como encontrar cada operação de leitura feita nesse intervalo na memória, selecionar todas as leituras que ocorrem antes de criar uma caixa de diálogo e, depois, classificar o resultado para encontrar a última operação de leitura.

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 tiver ocorrido um evento "dialog" em nosso rastreamento, podemos executar uma consulta para encontrar todas as operações de leitura feitas naquele intervalo na memória, selecionar todas as leituras que ocorrem antes da criação do diálogo e classificar o resultado para encontrar a última operação de leitura. Depois, viaje no tempo até esse ponto no tempo chamando SeekTo() na posição de tempo resultante.


: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

Laboratório de consulta TTD do GitHub

Para obter um tutorial sobre como depurar código C++ usando uma gravação de Depuração de Viagem no Tempo usando consultas para encontrar informações sobre a execução do código problemático em questão, consulte WinDbg-Samples – Depuração e Consultas de Viagem no Tempo.

Todo o código usado no laboratório pode ser encontrado aqui: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.

Solucionando consultas TTD

"UnknownOrMissingSymbols" como nomes das funções

A extensão do modelo de dados precisa ter informações completas de símbolo para dar os nomes de função, os valores de parâmetro, etc. Quando as informações completas do símbolo não estão disponíveis, o depurador usa "UnknownOrMissingSymbols" como nome da função.

  • Se tiver símbolos privados, você irá receber o nome da função e a lista correta de parâmetros.
  • Se tiver símbolos públicos, você receberá o nome da função e um conjunto padrão de parâmetros; quatro inteiros de 64 bits não assinados.
  • Se não tiver nenhuma informação de símbolo para o módulo que você está consultando, o nome usado será "UnknownOrMissingSymbols".

Consultas TTD para chamadas

Pode haver vários motivos pelos quais uma consulta não retorna nada para chamadas para uma DLL.

  • A sintaxe para a chamada não está correta. Tente verificar a sintaxe da chamada usando o x (Examinar símbolos) x <call>. Se o nome do módulo retornado por x estiver em maiúsculas, use esse nome.
  • A DLL ainda não foi carregada; ela será carregada depois no rastreamento. Para contornar essa viagem a um ponto no tempo depois que a DLL é carregada e refazer a consulta.
  • A chamada está embutida, de modo que o mecanismo de consulta não consegue rastrear.
  • O padrão da consulta usa curingas que retornam um excesso de funções. Tente especificar mais o padrão de consulta para que o número de funções correspondentes seja pequeno o suficiente.

Confira também

Usando LINQ com os objetos do depurador

dx (expressão para exibir modelo de objeto de depurador)

Depuração de viagem no tempo – Visão geral

Depuração de viagem no tempo - Automação JavaScript