Udostępnij przez


Wprowadzenie do obiektów debugowania podróży czasowych

Logo debugowania podróży w czasie przedstawiające zegar.

W tej sekcji opisano sposób używania modelu danych do wykonywania zapytań dotyczących śladów podróży w czasie. Może to być przydatne narzędzie do odpowiadania na pytania, takie jak te dotyczące kodu przechwyconego w śladzie podróży w czasie.

  • Jakie wyjątki znajdują się w śladzie?
  • W jakim momencie czasu w śledzeniu załadowano określony moduł kodu?
  • Kiedy wątki zostały utworzone/zakończone w śledzeniu?
  • Jakie są najdłużej działające wątki w śledzeniu?

Istnieją rozszerzenia TTD, które dodają dane do obiektów modelu sesji i przetwarzania danych. Dostęp do obiektów modelu danych TTD można uzyskać za pomocą polecenia dx (Display Debugger Object Model Expression), okna modelu WinDbg, JavaScript i C++. Rozszerzenia TTD są ładowane automatycznie podczas debugowania śledzenia podróży czasowej.

Przetwarzanie obiektów

Obiekty podstawowe dodane do obiektów Process można znaleźć w przestrzeni nazw TTD poza dowolnym obiektem Procesu . Na przykład @$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

Aby uzyskać ogólne informacje na temat pracy z zapytaniami LINQ i obiektami debugera, zobacz Using LINQ With the debugger objects (Używanie linQ z obiektami debugera).

Właściwości

Przedmiot Opis
Czas życia Obiekt zakresu TTD opisujący okres istnienia całego śladu.
Wątki Zawiera kolekcję obiektów wątków TTD, po jednym dla każdego wątku przez cały okres istnienia śledzenia.
Zdarzenia Zawiera kolekcję obiektów zdarzeń TTD, po jednym dla każdego zdarzenia w śladzie.

Metody

Metoda Opis
SetPosition() Przyjmuje liczbę całkowitą z zakresu od 0 do 100 lub ciąg w postaci N:N jako dane wejściowe i przenosi ślad do tej lokalizacji. Aby uzyskać więcej informacji, zobacz !tt .

Obiekty sesji

Obiekty podstawowe dodane do obiektów sesji można znaleźć w przestrzeni nazw TTD poza dowolnym obiektem sesji . Na przykład @$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)

Uwaga

Istnieją pewne obiekty i metody dodane przez TTDAnalyze, które są używane do funkcji wewnętrznych rozszerzenia. Nie wszystkie przestrzenie nazw są udokumentowane, a bieżące przestrzenie nazw ewoluują wraz z upływem czasu.

Metody

Metoda Opis
Data.Heap() Kolekcja obiektów sterty, które zostały przydzielone podczas śledzenia. Należy pamiętać, że jest to funkcja, która wykonuje obliczenia, więc uruchomienie zajmuje trochę czasu.
Wywołania() Zwraca kolekcję obiektów wywołań , które są zgodne z ciągiem wejściowym. Ciąg wejściowy może zawierać symbole wieloznaczne. Należy pamiętać, że jest to funkcja, która wykonuje obliczenia, więc uruchomienie zajmuje trochę czasu.
Pamięć() Jest to metoda, która przyjmuje parametry beginAddress, endAddress i dataAccessMask oraz zwraca kolekcję obiektów pamięci. Należy pamiętać, że jest to funkcja, która wykonuje obliczenia, więc uruchomienie zajmuje trochę czasu.

Sortowanie danych wyjściowych zapytania

Użyj metody OrderBy(), aby posortować wiersze zwrócone z zapytania według co najmniej jednej kolumny. W tym przykładzie sortuje się według czasu rozpoczęcia w kolejności rosnącej.

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

Aby wyświetlić dodatkową głębokość obiektów modelu danych, jest używana opcja -r2 poziomu rekursji. Aby uzyskać więcej informacji na temat opcji polecenia dx, zobacz dx (Display Debugger Object Model Expression).

W tym przykładzie sortowanie odbywa się według TimeStart w porządku malejącym.

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    

Określanie elementów w zapytaniu

Aby wybrać określony element, do zapytania można dołączyć różne kwalifikatory. Na przykład zapytanie wyświetla pierwsze wywołanie zawierające "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

Filtrowanie w zapytaniu

Użyj metody Select(), aby wybrać kolumny do wyświetlenia i zmodyfikować nazwę wyświetlaną kolumny.

W tym przykładzie zwracane są wiersze, w których ReturnValue nie wynosi zero, a kolumny TimeStart i ReturnValue są wyświetlane z niestandardowymi nazwami: Time i 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]

Grupowanie

Użyj metody GroupBy(), aby pogrupować dane zwrócone przez zapytanie w celu przeprowadzenia analizy przy użyciu wyników ustrukturyzowanych. Ten przykład grupuje lokalizacje czasu według numeru błędu.

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

Przypisywanie wyniku zapytania do zmiennej

Ta składnia służy do przypisywania wyniku zapytania do zmiennej dx @$var = <expression>

W tym przykładzie wyniki zapytania są przypisywane do obiektu myResults

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

Użyj polecenia dx, aby wyświetlić nowo utworzoną zmienną przy użyciu opcji siatki -g. Aby uzyskać więcej informacji na temat opcji polecenia dx, zobacz 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     =

Przykłady

Wykonywanie zapytań dotyczących wyjątków

To zapytanie LINQ używa obiektu TTD.Event do wyświetlania wszystkich wyjątków w śledzeniu.

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

Wykonywanie zapytań dotyczących określonych wywołań interfejsu API

Użyj obiektu TTD.Calls, aby wyszukiwać określone wywołania API. W tym przykładzie wystąpił błąd podczas wywoływania user32!MessageBoxW, z interfejsu API systemu Windows, który służy do wyświetlania okienka komunikatu. Wyświetlamy listę wszystkich wywołań funkcji MessageBoxW, porządkujemy je według godziny rozpoczęcia funkcji, a następnie wybieramy ostatnie wywołanie.

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

Wykonywanie zapytań o zdarzenie ładowania określonego modułu

Najpierw użyj polecenia lm (List Loaded Modules), aby wyświetlić załadowane moduły.

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)

Następnie użyj następującego polecenia dx, aby zobaczyć, na jakiej pozycji w śledzeniu załadowano określony moduł, taki jak 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 

To zapytanie LINQ wyświetla zdarzenia ładowania określonego modułu.

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

Adres FFFFFFFFFFFFFFFE:0 wskazuje zakończenie śledzenia.

Wykonywanie zapytań dotyczących wszystkich kontroli błędów w śledzeniu

Użyj tego polecenia, aby sortować wszystkie kontrole błędów w śledzeniu według liczby błędów.

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        =

Wykonywanie zapytań o położenie czasu w śladzie podczas tworzenia wątków

Użyj polecenia dx, aby wyświetlić wszystkie zdarzenia w śladzie w formacie siatki (-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... -                        =
==================================================================================================================================================================================================

Wybierz dowolną kolumnę z znakiem +, aby posortować dane wyjściowe.

Użyj tego zapytania LINQ, aby wyświetlić w formacie siatki, położenie czasu w śladzie podczas tworzenia wątków (Typ == "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]    =
===========================================================================================================

Użyj tego zapytania LINQ do wyświetlenia w formacie siatki pozycje czasowe w śladzie, gdy wątki zostały zakończone (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]    =
===========================================================================================================

Sortowanie danych wyjściowych w celu określenia najdłużej działających wątków

Użyj tego zapytania LINQ, aby wyświetlić w formacie siatki, przybliżone najdłużej działające wątki w śladzie.

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

Wykonywanie zapytań dotyczących dostępu do odczytu do zakresu pamięci

Użyj TTD.Memory object do wykonywania zapytań dotyczących dostępu do odczytu zakresu pamięci.

Blok środowiska wątku (TEB) to struktura zawierająca wszystkie informacje dotyczące stanu wątku, w tym wynik zwrócony przez metodę GetLastError(). Strukturę danych można zapytać, uruchamiając dx @$teb dla bieżącego wątku. Jednym z elementów członkowskich usługi TEB jest zmienna LastErrorValue o rozmiarze 4 bajtów. Możemy odwołać się do elementu LastErrorValue w bloku TEB przy użyciu tej składni. dx &@$teb->LastErrorValue.

Przykładowe zapytanie pokazuje, jak znaleźć każdą operację odczytu wykonaną w tym zakresie w pamięci, wybrać wszystkie operacje odczytu wykonywane przed utworzeniem okna dialogowego, a następnie posortować wynik, aby znaleźć ostatnią operację odczytu.

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]     

Jeśli w naszym śladzie było zdarzenie "okno dialogowe", możemy uruchomić zapytanie, aby znaleźć każdą operację odczytu wykonaną w tym zakresie w pamięci, wybrać wszystkie operacje odczytu, które mają miejsce przed utworzeniem okna dialogowego, a następnie posortować wynik, aby znaleźć ostatnią operację odczytu. Następnie przenieś się w czasie do tego punktu, wywołując funkcję SeekTo() na wynikowej pozycji czasu.


: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

Aby zapoznać się z samouczkiem dotyczącym debugowania kodu C++ przy użyciu rejestrowania debugowania podróży w czasie przy użyciu zapytań w celu znalezienia informacji na temat wykonywania problematycznego kodu, zobacz WinDbg-Samples — debugowanie podróży w czasie i zapytania.

Cały kod używany w laboratorium jest dostępny tutaj: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.

Rozwiązywanie problemów z zapytaniami TTD

"UnknownOrMissingSymbols" jako nazwy funkcji

Rozszerzenie modelu danych wymaga pełnych informacji o symbolach w celu zapewnienia nazw funkcji, wartości parametrów itp. Gdy pełne informacje o symbolach nie są dostępne, debuger używa jako nazwy funkcji "UnknownOrMissingSymbols".

  • Jeśli masz prywatne symbole, uzyskasz nazwę funkcji i poprawną listę parametrów.
  • Jeśli masz symbole publiczne, otrzymasz nazwę funkcji i domyślny zestaw parametrów — cztery niepodpisane 64-bitowe kropki.
  • Jeśli nie masz żadnych informacji o symbolach dla modułu, którego wykonujesz zapytanie, jako nazwę jest używana wartość "UnknownOrMisssingSymbols".

Zapytania TTD dotyczące połączeń

Istnieje kilka powodów, dla których zapytanie nie zwraca żadnych wywołań do biblioteki DLL.

  • Składnia wywołania nie jest prawidłowa. Spróbuj zweryfikować składnię wywołania przy użyciu symboli x (Sprawdź symbole).x <call> Jeśli nazwa modułu zwrócona przez znak x ma wielkie litery, użyj tej nazwy.
  • Biblioteka DLL nie jest jeszcze załadowana i zostaje załadowana później w przebiegu śledzenia. Aby obejść ten problem, przejdź do momentu w czasie po załadowaniu biblioteki DLL i powtórz zapytanie.
  • Wywołanie jest wbudowane, co sprawia, że silnik zapytań nie może go śledzić.
  • Wzorzec zapytania używa symboli wieloznacznych, co powoduje zwracanie zbyt wielu funkcji. Spróbuj uczynić wzorzec zapytania bardziej szczegółowym, aby liczba dopasowanych funkcji jest wystarczająco mała.

Zobacz też

używanie LINQ z obiektami debugera

dx (Display Debugger Object Model Expression)

Debugowanie podróży w czasie — omówienie

Debugowanie podróży w czasie — automatyzacja języka JavaScript