Compartir a través de


Introducción a los objetos de depuración de viajes en el tiempo

Logotipo de depuración de viajes en el tiempo con un reloj.

En esta sección se describe cómo utilizar el modelo de datos para consultar los rastreos de viajes en el tiempo. Puede ser una herramienta útil para responder a preguntas como estas sobre el código que se captura en un seguimiento de viaje en el tiempo.

  • ¿Qué excepciones hay en el rastreo?
  • ¿En qué momento del rastreo se cargó un módulo de código específico?
  • ¿Cuándo se crearon o finalizaron los subprocesos en el rastreo?
  • ¿Cuáles son los subprocesos de ejecución más largos del rastreo?

Existen extensiones TTD que añaden datos a los objetos del modelo de datos Sesión y Proceso. Se puede acceder a los objetos del modelo de datos TTD a través del comando dx (Mostrar la expresión del modelo de objeto del depurador), las ventanas de modelo de WinDbg, JavaScript y C++. Las extensiones TTD se cargan automáticamente al depurar una rastreo de viaje en el tiempo.

Procesar objetos

Los objetos primarios añadidos a los objetos Proceso se pueden encontrar en el espacio de nombres TTD fuera de cualquier objeto Proceso. Por ejemplo, @$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 obtener información general sobre cómo trabajar con consultas LINQ y objetos del depuradore, consulte Utilización de LINQ con los objetos del depurador.

Propiedades

Object Descripción
Tiempo de vida Un objeto de rango TTD que describe el tiempo de vida de todo el rastreo.
Subprocesos Contiene una colección de objetos de subproceso TTD, uno por cada subproceso a lo largo de la vida del rastreo.
Eventos Contiene una colección de objetos de evento TTD, uno por cada evento del rastreo.

Métodos

método Descripción
SetPosition() Toma un entero entre 0 y 100 o una cadena en forma N:N como entrada y salta el rastreo a esa posición. Consulte !tt para obtener más información.

Objetos de sesión

Los objetos primarios añadidos a los objetos Sesión se pueden encontrar en el espacio de nombres TTD fuera de cualquier objeto Sesión. Por ejemplo, @$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)

Nota:

Hay algunos objetos y métodos añadidos por TTDAnalyze que se utilizan para funciones internas de la extensión. No todos los espacios de nombres están documentados, y los actuales evolucionarán con el tiempo.

Métodos

método Descripción
Data.Heap() Una colección de objetos del montón que fueron asignados durante el rastreo. Tenga en cuenta que se trata de una función que realiza cálculos, por lo que tarda un poco en ejecutarse.
Calls() Devuelve una colección de objetos de llamadas que coinciden con la cadena de entrada. La cadena de entrada puede contener caracteres comodín. Tenga en cuenta que se trata de una función que realiza cálculos, por lo que tarda un poco en ejecutarse.
Memory() Este es un método que toma los parámetros beginAddress, endAddress y dataAccessMask y devuelve una colección de objetos de memoria. Tenga en cuenta que se trata de una función que realiza cálculos, por lo que tarda un poco en ejecutarse.

Clasificación de los resultados de la consulta

Utilice el método OrderBy() para ordenar las filas devueltas por la consulta en una o más columnas. Este ejemplo ordena por TimeStart en orden ascendente.

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 una profundidad adicional de los objetos del modelo de datos se utiliza la opción de nivel de recursión -r2. Para obtener más información sobre las opciones del comando dx, consulte dx (Mostrar la expresión del modelo de objeto del depurador).

Este ejemplo ordena por TimeStart en orden descendente.

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    

Especificación de elementos en una consulta

Para seleccionar un elemento concreto, se pueden añadir varios calificadores a la consulta. Por ejemplo, la consulta muestra la primera llamada que contiene "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

Filtrado en una consulta

Utilice el método Select() para elegir qué columnas ver y modificar el nombre de visualización de la columna.

Este ejemplo devuelve filas en las que ReturnValue no es cero y selecciona mostrar las columnas TimeStart y ReturnValue con nombres de visualización personalizados de Tiempo y 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]

Agrupación

Utilice el método GroupBy() para agrupar los datos devueltos por la consulta y realizar análisis utilizando resultados estructurados. Este ejemplo agrupa las ubicaciones de tiempo por número de error.

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

Asignación del resultado de una consulta a una variable

Use esta sintaxis para asignar el resultado de una consulta a una variable dx @$var = <expression>

En este ejemplo se asignan los resultados de una consulta a myResults.

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

Use el comando dx para mostrar la variable recién creada mediante la opción de cuadrícula -g. Para obtener más información sobre las opciones del comando dx, consulte dx (Mostrar la expresión del modelo de objeto del 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     =

Ejemplos

Consultar si hay excepciones

Esta consulta LINQ usa el objeto TTD.Event para mostrar todas las excepciones del rastreo.

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 de llamadas específicas a la API

Use el objeto TTD.Calls para consultar llamadas específicas a la API. En este ejemplo, se ha producido un error al llamar a user32!MessageBoxW, la API de Windows para mostrar un cuadro de mensaje. Enumeramos todas las llamadas a MessageBoxW , las ordenamos por la hora de inicio de la función y elegimos la última llamada.

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

Consulta del evento de carga de un módulo específico

En primer lugar, use el comando lm (Enumerar módulos cargados) para mostrar los módulos cargados.

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)

A continuación, utilice el siguiente comando dx para ver en qué posición del rastreo se cargó un módulo específico, 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 muestra los eventos de carga de un módulo concreto.

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

La dirección de FFFFFFFFFFFFFFFE:0 indica el final del rastreo.

Consulta de todas las comprobaciones de errores en el rastreo

Utilice este comando para ordenar todas las comprobaciones de errores del rastreo por recuento de errores.

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        =

Consulta de la posición de tiempo en el rastreo en la que se crearon los subprocesos

Utilice este comando dx para visualizar todos los eventos del rastreo en formato de cuadrícula (-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... -                        =
==================================================================================================================================================================================================

Seleccione cualquiera de las columnas con el signo + para ordenar la salida.

Utilice esta consulta LINQ para mostrar en formato de cuadrícula la posición temporal en el rastreo en la que se crearon los subprocesos (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]    =
===========================================================================================================

Utilice esta consulta LINQ para mostrar, en formato de cuadrícula, las posiciones de tiempo en el rastreo cuando se puso fina los subprocesos (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]    =
===========================================================================================================

Ordenar la salida para determinar los subprocesos en ejecución más largos

Use esta consulta LINQ para mostrar, en formato de cuadrícula, los subprocesos de ejecución más largos aproximados en el rastreo.

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

Consulta de accesos de lectura a un intervalo de memoria

Use el objeto TTD.Memory para consultar los accesos de lectura a un intervalo de memoria.

El bloque de entorno de subprocesos (TEB) es una estructura que contiene toda la información relativa al estado de un subproceso, incluido el resultado devuelto por GetLastError(). Puede consultar esta estructura de datos ejecutando dx @$teb para el subproceso actual. Uno de los miembros de TEB es una variable LastErrorValue, de 4 bytes de tamaño. Podemos hacer referencia al miembro LastErrorValue en el TEB utilizando esta sintaxis. dx &@$teb->LastErrorValue.

La consulta de ejemplo muestra cómo encontrar todas las operaciones de lectura realizadas en ese intervalo de memoria, seleccionar todas las lecturas que se produjeron antes de que se creara un diálogo y, a continuación, ordenar el resultado para encontrar la última operación de lectura.

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]     

Si en nuestro rastreo se ha producido un evento "diálogo", podemos ejecutar una consulta para encontrar todas las operaciones de lectura realizadas en ese intervalo de memoria, seleccionar todas las lecturas que se produjeron antes de que se creara el diálogo y, a continuación, ordenar el resultado para encontrar la última operación de lectura. A continuación, viaje en el tiempo hasta ese punto llamando a SeekTo() en la posición de tiempo 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

Laboratorio de consultas TTD de GitHub

Para ver un tutorial sobre cómo depurar código de C++ mediante una grabación de depuración de viaje de tiempo mediante consultas para encontrar información sobre la ejecución del código problemático en cuestión, vea WinDbg-Samples - Time Travel Debugging and Queries.

Todo el código usado en el laboratorio está disponible aquí: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.

Solucionar problemas de consultas TTD

"UnknownOrMissingSymbols" como nombres de función

La extensión del modelo de datos necesita la información completa de los símbolos para proporcionar los nombres de las funciones, los valores de los parámetros, etc. Cuando la información de símbolos completa no está disponible, el depurador utiliza "UnknownOrMissingSymbols" como nombre de función.

  • Si tiene símbolos privados, obtendrá el nombre de la función y la lista correcta de parámetros.
  • Si tiene símbolos públicos obtendrá el nombre de la función y un conjunto de parámetros por defecto - cuatro ints de 64 bits sin firma.
  • Si no dispone de información sobre símbolos para el módulo que está consultando, se utilizará "UnknownOrMissingSymbols" como nombre.

Consultas TTD para llamadas

Puede haber varias razones por las que una consulta no devuelve nada para las llamadas a un archivo DLL.

  • La sintaxis de la llamada no es correcta. Pruebe a comprobar la sintaxis de llamada mediante x (Examinar símbolos). x <call> Si el nombre del módulo devuelto por x está en mayúsculas, úselo.
  • La DLL aún no está cargada y se carga más adelante en el rastreo. Para solucionar este problema, desplácese a un momento posterior a la carga de la DLL y vuelva a realizar la consulta.
  • La llamada está en línea, por lo que el motor de consultas no puede rastrearla.
  • El patrón de consulta utiliza comodines que devuelven demasiadas funciones. Intente que el patrón de consulta sea más específico para que el número de funciones coincidentes sea lo suficientemente pequeño.

Consulte también

Uso de LINQ con los objetos del depurador

dx (Mostrar la expresión del modelo de objeto del depurador)

Depuración de viajes en el tiempo - Información general

Depuración de viajes en el tiempo - Automatización de JavaScript