Bagikan melalui


Pengantar objek Time Travel Debugging

Logo penelusuran kesalahan perjalanan waktu yang menampilkan jam.

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

  • Pengecualian apa yang ada dalam jejak?
  • Pada titik waktu berapa dalam pelacakan melakukan pemuatan modul kode tertentu?
  • Kapan utas dibuat/dihentikan 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 menelusuri kesalahan pelacakan perjalanan waktu.

Objek Proses

Objek utama yang ditambahkan ke objek Proses dapat ditemukan di namespace TTD dari objek Proses apa pun. Contohnya,@$curprocess.TTD.

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

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

Properti

Objek Deskripsi
Seumur hidup Objek rentang TTD yang menjelaskan masa pakai seluruh jejak.
Utas Berisi kumpulan objek utas TTD, satu untuk setiap utas sepanjang masa pakai pelacakan.
Peristiwa Berisi kumpulan objek peristiwa TTD, satu untuk setiap peristiwa dalam pelacakan.

Metode

Metode Deskripsi
SetPosition() Mengambil bilangan bulat antara 0 dan 100 atau string dalam bentuk N:N sebagai input dan melompat 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                 : [object Object]
    Calls            [Returns call information from the trace for the specified set of methods: TTD.Calls("module!method1", "module!method2", ...) For example: dx @$cursession.TTD.Calls("user32!SendMessageA")]
    Memory           [Returns memory access information for specified address range: TTD.Memory(startAddress, endAddress [, "rwec"])]
    DefaultParameterCount : 0x4
    AsyncQueryEnabled : false
    Resources       
    Data             : Normalized data sources based on the contents of the time travel trace
    Utility          : Methods that can be useful when analyzing time travel traces

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 tumpukan 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 input dapat berisi kartubebas. 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 output 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)                
    [0xb]           
        EventType        : Call
        ThreadId         : 0x3a10
        UniqueThreadId   : 0x2
        TimeStart        : 39:2DC [Time Travel]
        TimeEnd          : 39:2DF [Time Travel]
        Function         : UnknownOrMissingSymbols
        FunctionAddress  : 0x7561ccc0
        ReturnAddress    : 0x7593d24c
        ReturnValue      : 0x0
        Parameters      
    [0xe]           
        EventType        : Call
        ThreadId         : 0x3a10
        UniqueThreadId   : 0x2
        TimeStart        : AF:36 [Time Travel]
        TimeEnd          : AF:39 [Time Travel]
        Function         : UnknownOrMissingSymbols
        FunctionAddress  : 0x7561ccc0
        ReturnAddress    : 0x4723ef
        ReturnValue      : 0x0
        Parameters  

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        : Call
    ThreadId         : 0x3a10
    UniqueThreadId   : 0x2
    TimeStart        : 77A:9 [Time Travel]
    TimeEnd          : 77A:C [Time Travel]
    Function         : UnknownOrMissingSymbols
    FunctionAddress  : 0x7561ccc0
    ReturnAddress    : 0x6cf12406
    ReturnValue      : 0x0
    Parameters    

Pemfilteran dalam kueri

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 })                
    [0x13]          
        Time             : 3C64A:834 [Time Travel]
        Error            : 0x36b7
    [0x1c]          
        Time             : 3B3E7:D6 [Time Travel]
        Error            : 0x3f0
    [0x1d]          
        Time             : 3C666:857 [Time Travel]
        Error            : 0x36b7
    [0x20]          
        Time             : 3C67E:12D [Time Travel]

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

Mengkueri untuk pengecualian

Kueri LINQ ini menggunakan TTD. Objek peristiwa 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 , memesannya pada 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

Mengkueri untuk peristiwa beban 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 menurut semua pemeriksaan kesalahan dalam jumlah kesalahan jejak menurut.

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        =

Mengkueri untuk posisi waktu dalam pelacakan saat 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 dalam format kisi, posisi waktu dalam jejak 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 terlama yang berjalan

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

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 TTD. Objek memori yang akan dikueri 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 bisa mengkueri struktur data ini dengan menjalankan dx @$teb 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 men-debug kode C++ menggunakan rekaman Time Travel Debugging menggunakan kueri untuk menemukan informasi tentang eksekusi kode bermasalah yang dimaksud, lihat https://github.com/Microsoft/WinDbg-Samples/blob/master/TTDQueries/tutorial-instructions.md.

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 ints 64-bit yang tidak ditandatangani.
  • Jika Anda tidak memiliki informasi simbol untuk modul yang Anda kueri, maka "UnknownOrMissingSymbols" digunakan sebagai nama.

Kueri TTD untuk panggilan

Mungkin ada beberapa alasan kueri tidak mengembalikan apa pun untuk panggilan ke DLL.

  • Sintaks untuk panggilan tidak benar. Coba verifikasi sintaks panggilan dengan menggunakan perintah x: "x <call>". Jika nama modul yang dikembalikan oleh x dalam huruf besar, gunakan itu.
  • DLL belum dimuat dan dimuat nanti di jejak. Untuk mengatasi perjalanan ini ke titik waktu setelah DLL dimuat dan ulangi kueri.
  • Panggilan di-inlin 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

Penelusuran Kesalahan Perjalanan Waktu - Otomatisasi JavaScript