Bagikan melalui


Pengantar objek Time Travel Debugging

Logo debugging perjalanan waktu dengan fitur jam.

Bagian ini menjelaskan cara menggunakan model data untuk mengkueri jejak perjalanan waktu. Ini bisa menjadi alat yang berguna untuk menjawab pertanyaan seperti ini tentang kode yang ditangkap dalam jejak perjalanan waktu.

  • Pengecualian apa yang ada dalam pelacakan?
  • Pada titik waktu berapa dalam pelacakan melakukan pemuatan modul kode tertentu?
  • Kapan utas dibuat/dihentikan operasinya dalam pelacakan?
  • Apa utas terlama dalam pelacakan?

Ada ekstensi TTD yang menambahkan data ke objek model data Sesi dan Proses . Objek model data TTD dapat diakses melalui perintah dx (Ekspresi Model Objek Debugger Tampilan), jendela model WinDbg, JavaScript, dan C++. Ekstensi TTD dimuat secara otomatis saat melakukan debugging jejak perjalanan waktu.

Objek Proses

Objek utama yang ditambahkan ke objek Proses dapat ditemukan di namespace TTD dari objek Proses mana pun. Contohnya,@$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

Untuk informasi umum tentang bekerja dengan kueri LINQ dan objek debugger, lihat Menggunakan LINQ Dengan objek debugger.

Properti

Objek Deskripsi
Seumur hidup Satu objek rentang TTD yang menjelaskan masa hidup seluruh penelusuran.
Utas Berisi kumpulan objek utas TTD, satu untuk setiap utas sepanjang masa pakai pelacakan.
Acara Berisi kumpulan objek peristiwa TTD, masing-masing mewakili peristiwa dalam jejak.

Metode

Metode Deskripsi
SetPosition() Menerima bilangan bulat yang nilainya antara 0 dan 100 atau string dalam bentuk N:N sebagai input dan memindahkan jejak ke lokasi tersebut. Lihat !tt untuk informasi selengkapnya.

Objek Sesi

Objek utama yang ditambahkan ke objek Sesi dapat ditemukan di namespace TTD dari objek Sesi apa pun. Contohnya,@$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)

Catatan

Ada beberapa objek dan metode yang ditambahkan oleh TTDAnalyze yang digunakan untuk fungsi internal ekstensi. Tidak semua namespace didokumenkan, dan namespace saat ini akan berkembang dari waktu ke waktu.

Metode

Metode Deskripsi
Data.Heap() Kumpulan objek heap yang dialokasikan selama pelacakan. Perhatikan bahwa ini adalah fungsi yang melakukan komputasi, sehingga perlu waktu cukup lama untuk dijalankan.
Panggilan() Mengembalikan kumpulan objek panggilan yang cocok dengan string input. String masukan dapat berisi karakter pengganti. Perhatikan bahwa ini adalah fungsi yang melakukan komputasi, sehingga perlu waktu cukup lama untuk dijalankan.
Memori() Ini adalah metode yang mengambil parameter beginAddress, endAddress, dan dataAccessMask dan mengembalikan kumpulan objek memori. Perhatikan bahwa ini adalah fungsi yang melakukan komputasi, sehingga perlu waktu cukup lama untuk dijalankan.

Mengurutkan hasil kueri

Gunakan metode OrderBy() untuk mengurutkan baris yang dikembalikan dari kueri menurut satu atau beberapa kolom. Contoh ini mengurutkan menurut TimeStart dalam urutan naik.

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

Untuk menampilkan kedalaman tambahan objek model data, opsi tingkat rekursi -r2 digunakan. Untuk informasi selengkapnya tentang opsi perintah dx, lihat dx (Ekspresi Model Objek Debugger Tampilan).

Contoh ini mengurutkan menurut TimeStart dalam urutan turun.

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    

Menentukan elemen dalam kueri

Untuk memilih elemen tertentu, berbagai kualifikasi dapat ditambahkan ke kueri. Misalnya, kueri menampilkan panggilan pertama yang berisi "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

Pemfilteran dalam pertanyaan

Gunakan metode Select() untuk memilih kolom mana yang akan dilihat dan memodifikasi nama tampilan kolom.

Contoh ini mengembalikan baris di mana ReturnValue bukan nol dan memilih untuk menampilkan kolom TimeStart dan ReturnValue dengan nama tampilan kustom Waktu dan Kesalahan.

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]

Pengelompokan

Gunakan metode GroupBy() untuk mengelompokkan data yang dikembalikan oleh kueri untuk melakukan analisis menggunakan hasil terstruktur Contoh ini mengelompokkan lokasi waktu menurut nomor kesalahan.

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

Menetapkan hasil kueri ke variabel

Gunakan sintaks ini untuk menetapkan hasil kueri ke variabel dx @$var = <expression>

Contoh ini menetapkan hasil kueri ke myResults

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

Gunakan perintah dx untuk menampilkan variabel yang baru dibuat menggunakan opsi kisi -g. Untuk informasi selengkapnya tentang opsi perintah dx, lihat dx (Ekspresi Model Objek Debugger Tampilan).

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     =

Contoh

Mencari pengecualian

Kueri LINQ ini menggunakan objek TTD.Event untuk menampilkan semua pengecualian dalam pelacakan.

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

Mengkueri untuk panggilan API tertentu

Gunakan TTD. Memanggil objek untuk mengkueri panggilan API tertentu. Dalam contoh ini, terjadi kesalahan saat memanggil pengguna32! MessageBoxW, WINDOWS API untuk menampilkan kotak pesan. Kami mencantumkan semua panggilan ke MessageBoxW, mengurutkannya berdasarkan waktu mulai fungsi, lalu memilih panggilan terakhir.

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

Menanyakan peristiwa pemuatan modul tertentu

Pertama, gunakan perintah lm (List Loaded Modules) untuk menampilkan modul yang dimuat.

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)

Kemudian gunakan perintah dx berikut untuk melihat posisi apa dalam jejak modul tertentu yang dimuat, seperti 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 

Kueri LINQ ini menampilkan peristiwa beban modul tertentu.

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

Alamat FFFFFFFFFFFFFFFFFE:0 menunjukkan akhir jejak.

Mengkueri untuk semua pemeriksaan kesalahan dalam pelacakan

Gunakan perintah ini untuk mengurutkan semua pemeriksaan kesalahan dalam pelacakan berdasarkan jumlah kesalahan.

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        =

Menanyakan tentang posisi waktu dalam pelacakan ketika utas dibuat

Gunakan perintah dx ini untuk menampilkan semua peristiwa dalam pelacakan dalam format kisi (-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... -                        =
==================================================================================================================================================================================================

Pilih salah satu kolom dengan tanda + untuk mengurutkan output.

Gunakan kueri LINQ ini untuk menampilkan dalam format kisi, posisi waktu dalam jejak saat utas dibuat (Tipe == "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]    =
===========================================================================================================

Gunakan kueri LINQ ini untuk menampilkan posisi waktu dalam jejak pada format tabel ketika utas dihentikan (Tipe == "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]    =
===========================================================================================================

Mengurutkan output untuk menentukan utas yang berjalan paling lama

Gunakan kueri LINQ ini untuk menampilkan perkiraan utas terlama dalam pelacakan dalam format tabel.

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

Mengkueri akses baca ke rentang memori

Gunakan objek TTD.Memory untuk mengkueri akses baca ke rentang memori.

Blok Lingkungan Utas (TEB) adalah struktur yang berisi semua informasi mengenai status utas, termasuk hasil yang dikembalikan oleh GetLastError(). Anda dapat membuat kueri struktur data ini dengan menjalankan dx @$teb untuk utas saat ini. Salah satu anggota TEB adalah variabel LastErrorValue, berukuran 4 byte. Kita dapat mereferensikan anggota LastErrorValue di TEB menggunakan sintaks ini. dx &@$teb->LastErrorValue.

Contoh kueri memperlihatkan cara menemukan setiap operasi baca yang dilakukan dalam rentang tersebut dalam memori, pilih semua bacaan yang terjadi sebelum dialog dibuat lalu urutkan hasilnya untuk menemukan operasi baca terakhir.

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]     

Jika dalam pelacakan kami peristiwa "dialog" telah terjadi, kita dapat menjalankan kueri untuk menemukan setiap operasi baca yang dilakukan dalam rentang tersebut dalam memori, pilih semua bacaan yang terjadi sebelum dialog dibuat lalu urutkan hasilnya untuk menemukan operasi baca terakhir. Kemudian perjalanan waktu ke titik waktu tersebut dengan memanggil SeekTo() pada posisi waktu yang dihasilkan.


: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

Lab Kueri TTD GitHub

Untuk tutorial tentang cara mendebug kode C++ menggunakan rekaman Debugging Penyusuran Waktu dengan kueri untuk menemukan informasi tentang eksekusi kode yang menjadi masalah tersebut, lihat WinDbg-Samples - Time Travel Debugging and Queries.

Semua kode yang digunakan di lab tersedia di sini: https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample.

Pemecahan Masalah Kueri TTD

"UnknownOrMissingSymbols" sebagai nama fungsi

Ekstensi model data memerlukan informasi simbol penuh untuk memberikan nama fungsi, nilai parameter, dll. Ketika informasi simbol lengkap tidak tersedia, debugger menggunakan "UnknownOrMissingSymbols" sebagai nama fungsi.

  • Jika Anda memiliki simbol privat, Anda akan mendapatkan nama fungsi dan daftar parameter yang benar.
  • Jika Anda memiliki simbol publik, Anda akan mendapatkan nama fungsi dan sekumpulan parameter default - empat integer 64-bit yang tidak bertanda.
  • Jika Anda tidak memiliki informasi simbol untuk modul yang Anda kueri, maka "UnknownOrMissingSymbols" digunakan sebagai nama.

Kueri TTD untuk panggilan

Mungkin ada beberapa alasan mengapa kueri tidak mengembalikan hasil apa pun saat memanggil DLL.

  • Sintaks untuk panggilan tidak sepenuhnya benar. Coba verifikasi sintaks panggilan dengan menggunakan x (Periksa Simbol)x <call>. Jika nama modul yang dikembalikan oleh x dalam huruf besar, gunakan itu.
  • DLL belum dimuat sama sekali dan dimuat nanti dalam pelacakan. Untuk mengatasi perjalanan ini ke titik waktu setelah DLL dimuat dan ulangi kueri.
  • Panggilan diintegrasikan secara langsung yang tidak dapat dilacak oleh mesin kueri.
  • Pola kueri menggunakan kartubebas yang mengembalikan terlalu banyak fungsi. Cobalah untuk membuat pola kueri lebih spesifik sehingga jumlah fungsi yang cocok cukup kecil.

Lihat Juga

Menggunakan LINQ Dengan objek debugger

dx (Ekspresi Model Objek Debugger Tampilan)

Penelusuran Kesalahan Perjalanan Waktu - Gambaran Umum

Debugging Time Travel - Otomatisasi JavaScript