Pengantar objek Time Travel Debugging
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