Bagikan melalui


WinDbg: Garis Waktu

logo WinDbg dengan kaca pembesar yang memeriksa bit.

Time Travel Debugging (TTD) memungkinkan pengguna untuk merekam jejak, yang merupakan rekaman eksekusi program. Garis waktu adalah representasi visual peristiwa yang terjadi selama eksekusi. Peristiwa ini dapat menjadi lokasi titik henti, baca/tulis memori, panggilan dan pengembalian fungsi, dan pengecualian.

Cuplikan layar garis waktu di debugger yang menampilkan pengecualian, akses memori, titik henti, dan panggilan fungsi.

Gunakan jendela Garis Waktu untuk melihat peristiwa penting, memahami posisi relatifnya, dan dengan mudah melompat ke lokasinya di file pelacakan TTD Anda. Gunakan beberapa garis waktu untuk menjelajahi peristiwa secara visual dalam pelacakan perjalanan waktu dan menemukan korelasi peristiwa.

Jendela Garis Waktu muncul saat Anda membuka file pelacakan TTD. Ini menunjukkan peristiwa utama tanpa Anda harus membuat kueri model data secara manual. Pada saat yang sama, semua objek perjalanan waktu tersedia untuk memungkinkan kueri data yang lebih kompleks.

Untuk informasi selengkapnya tentang cara membuat dan bekerja dengan file pelacakan perjalanan waktu, lihat Penelusuran Kesalahan Perjalanan Waktu: Gambaran Umum.

Jenis garis waktu

Jendela Garis Waktu memperlihatkan peristiwa dalam garis waktu berikut:

  • Pengecualian: Anda dapat memfilter kode pengecualian tertentu.
  • Titik henti: Anda dapat melihat kapan titik henti mencapai garis waktu.
  • Akses Memori: Anda dapat membaca, menulis, dan menjalankan di antara dua alamat memori.
  • Panggilan Fungsi: Anda dapat mencari dalam bentuk module!function.

Arahkan penunjuk mouse ke atas setiap event untuk mendapatkan informasi lebih lanjut melalui tooltip. Memilih event memproses kueri untuk event tersebut dan menampilkan informasi lebih lanjut. Mengklik dua kali pada sebuah peristiwa akan membawa Anda ke lokasi tersebut di file pelacakan TTD.

Pengecualian

Saat Anda memuat file pelacakan dan garis waktu aktif, file tersebut menampilkan pengecualian apa pun dalam rekaman secara otomatis.

Saat Anda mengarahkan mouse ke titik henti, informasi seperti jenis pengecualian dan kode pengecualian muncul.

Cuplikan layar garis waktu di debugger yang menampilkan pengecualian dengan informasi tentang kode pengecualian tertentu.

Anda dapat memfilter lebih lanjut pada kode pengecualian tertentu dengan menggunakan bidang Kode Pengecualian opsional.

Cuplikan tampilan layar kotak dialog pengecualian lini masa debugger dengan Jenis Lini Masa diatur ke Pengecualian dan Kode Pengecualian diatur ke 0xC0000004.

Anda juga dapat menambahkan garis waktu baru untuk jenis pengecualian tertentu.

Titik Pemutus

Setelah Anda menambahkan titik henti, posisi pada garis waktu menunjukkan kapan titik henti tersebut tercapai. Misalnya, Anda dapat menggunakan perintah bp Set Breakpoint. Saat Anda mengarahkan mouse ke atas titik henti, alamat dan penunjuk instruksi yang terkait dengan titik henti muncul.

Cuplikan layar garis waktu di debugger menampilkan sekitar 30 indikator titik henti.

Saat titik henti dibersihkan, garis waktu titik henti terkait akan dihapus secara otomatis.

Panggilan fungsi

Anda dapat melihat posisi panggilan fungsi pada garis waktu. Untuk melakukan langkah ini, berikan pencarian dalam bentuk module!function. Contohnya adalah TimelineTestCode!multiplyTwo. Anda juga dapat menentukan wildcard, misalnya, TimelineTestCode!m*.

Cuplikan layar menambahkan garis waktu di debugger dengan nama panggilan fungsi yang dimasukkan.

Saat Anda mengarahkan mouse ke atas panggilan fungsi, nama fungsi, parameter input, nilainya, dan nilai pengembalian muncul. Contoh ini menunjukkan buffer dan ukuran karena merupakan parameter untuk DisplayGreeting!GetCppConGreeting.

Cuplikan layar linimasa di debugger yang menampilkan panggilan fungsi dan jendela Registers.

Akses memori

Gunakan garis waktu Akses Memori untuk melihat kapan rentang memori tertentu dibaca atau ditulis, atau tempat eksekusi kode berlangsung. Alamat mulai dan berhenti digunakan untuk menentukan rentang antara dua alamat memori.

Cuplikan layar menampilkan dialog Akses Memori yang ditambahkan dengan opsi Tulis yang dipilih.

Saat Anda mengarahkan mouse ke atas item akses memori, nilai dan penunjuk instruksi muncul.

Cuplikan layar garis waktu di debugger yang menampilkan peristiwa akses memori.

Bekerja dengan garis waktu

Garis abu-abu vertikal mengikuti kursor saat Anda mengarahkan kursor ke garis waktu. Garis biru vertikal menunjukkan posisi saat ini dalam pelacakan.

Pilih ikon kaca pembesar untuk memperbesar dan memperkecil garis waktu.

Di area kontrol garis waktu atas, gunakan persegi panjang untuk menggeser tampilan garis waktu. Seret pemisah luar persegi panjang untuk mengubah ukuran tampilan garis waktu saat ini.

Cuplikan layar garis waktu di debugger memperlihatkan area atas yang digunakan untuk memilih tampilan aktif.

Gerakan mouse

Untuk memperbesar dan memperkecil, pilih Ctrl dan gunakan roda gulir.

Untuk menggeser dari sisi ke sisi, pilih Geser dan gunakan roda gulir.

Teknik penelusuran kesalahan garis waktu

Untuk mendemonstrasikan teknik debugging garis waktu, Time Travel Debugging walkthrough digunakan kembali di sini. Demonstrasi ini mengasumsikan bahwa Anda menyelesaikan dua langkah pertama untuk membangun kode sampel dan membuat rekaman TTD dengan menggunakan dua langkah pertama yang dijelaskan di sana.

Dalam skenario ini, langkah pertama adalah menemukan pengecualian dalam jejak perjalanan waktu. Klik dua kali satu-satunya pengecualian yang Anda lihat di garis waktu.

Di jendela Perintah , Anda dapat melihat bahwa perintah berikut dikeluarkan saat Anda memilih pengecualian.

(2dcc.6600): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: CC:0
@$curprocess.TTD.Events.Where(t => t.Type == "Exception")[0x0].Position.SeekTo()

Pilih Lihat>Register untuk menampilkan register pada titik ini di garis waktu guna memulai penyelidikan.

Cuplikan layar pada debugger yang menampilkan linimasa pengecualian ‘lab demo’ dan jendela Register.

Dalam output perintah, tumpukan (esp) dan penunjuk dasar (ebp) menunjuk ke alamat yang berbeda. Perbedaan ini dapat menunjukkan kerusakan tumpukan. Mungkin, fungsi dikembalikan dan kemudian merusak tumpukan. Untuk memvalidasi masalah ini, kembali ke sebelum status CPU rusak dan lihat apakah Anda dapat menentukan kapan kerusakan tumpukan terjadi.

Saat Anda melakukan proses itu, periksa nilai variabel lokal dan tumpukannya:

  • Pilih Tampilkan>Lokal untuk menampilkan nilai lokal.
  • Pilih Tampilkan>Tumpukan untuk menampilkan tumpukan eksekusi kode.

Pada titik kegagalan, dalam pelacakan, biasanya kita berada beberapa langkah setelah menemukan penyebab sebenarnya di dalam kode penanganan kesalahan. Dengan perjalanan kembali ke masa lalu, Anda dapat menelusuri satu per satu instruksi untuk menemukan akar penyebab sebenarnya.

Pada pita Beranda , gunakan perintah Langkah Ke Belakang untuk melangkah mundur tiga instruksi. Saat Anda melakukan proses ini, lanjutkan untuk memeriksa jendela Stack, Locals, dan Registers .

Jendela Command menampilkan posisi perjalanan waktu dan register ketika Anda melangkah mundur tiga instruksi.

0:000> t-
Time Travel Position: CB:41
eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=00540020 esp=003cf7d0 ebp=00520055 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
00540020 ??              ???
0:000> t-
Time Travel Position: CB:40
eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=00061767 esp=003cf7cc ebp=00520055 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
DisplayGreeting!main+0x57:
00061767 c3              ret
0:000> t-
Time Travel Position: CB:3A
eax=0000004c ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=0006175f esp=003cf718 ebp=003cf7c8 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
DisplayGreeting!main+0x4f:
0006175f 33c0            xor     eax,eax

Pada titik ini dalam pelacakan, tumpukan dan penunjuk basis Anda memiliki nilai yang lebih masuk akal. Tampaknya Anda semakin dekat dengan titik dalam kode tempat kerusakan terjadi.

esp=003cf718 ebp=003cf7c8

Jendela Lokal berisi nilai dari aplikasi target Anda. Jendela Kode sumber menyoroti baris kode yang siap dijalankan dalam kode sumber Anda pada titik ini dalam pelacakan.

Untuk menyelidiki lebih lanjut, buka jendela Memori untuk melihat konten di dekat alamat memori penunjuk tumpukan (esp). Dalam contoh ini, ia memiliki nilai 003cf7c8. PilihAscii>> untuk menampilkan teks ASCII yang disimpan di alamat tersebut.

Cuplikan layar debugger yang menampilkan jendela Registers, Stack, dan Memory.

Garis waktu akses memori

Setelah lokasi memori yang menarik diidentifikasi, gunakan nilai tersebut untuk menambahkan garis waktu akses memori. Pilih + Tambahkan garis waktu dan isi alamat awal. Lihat 4 byte agar ketika Anda menambahkannya ke nilai Alamat Mulai, Anda memiliki nilai Alamat Akhir.003cf7cb Defaultnya adalah melihat semua penulisan memori, tetapi Anda juga dapat melihat hanya penulisan atau eksekusi kode di alamat tersebut.

Cuplikan layar dari menambahkan dialog akses memori pada garis waktu dengan opsi Tulis yang dipilih dan nilai awal 003cf7c8.

Sekarang Anda dapat melintasi garis waktu secara mundur untuk memeriksa pada titik mana dalam jejak penelusuran ini lokasi memori tersebut ditulis dan melihat apa yang dapat Anda temukan. Saat Anda memilih posisi ini di garis waktu, Anda dapat melihat bahwa nilai lokal berbeda untuk string yang sedang disalin. Nilai tujuan tampaknya tidak lengkap, seolah-olah panjang string Anda tidak benar.

Cuplikan layar garis waktu akses memori dan jendela Lokal yang menampilkan nilai lokal dengan nilai sumber dan tujuan yang berbeda.

Garis waktu titik henti

Menggunakan titik henti adalah pendekatan umum untuk menjeda eksekusi kode pada beberapa peristiwa yang menarik. Dengan TTD, Anda dapat mengatur titik henti dan memutar kembali waktu sampai mencapai titik henti tersebut setelah pelacakan direkam. Kemampuan untuk memeriksa status proses setelah masalah terjadi, menentukan lokasi terbaik untuk titik henti, memungkinkan lebih banyak alur kerja debugging yang unik untuk TTD.

Untuk menjelajahi teknik penelusuran kesalahan pada garis waktu alternatif, pilih pengecualian di garis waktu dan kemudian mundur tiga langkah dengan menggunakan perintah Langkah Ke Belakang pada pita Beranda.

Dalam sampel kecil ini, mudah untuk memeriksa kode. Jika Anda memiliki ratusan baris kode dan puluhan subroutine, gunakan teknik yang dijelaskan di sini untuk mengurangi waktu yang diperlukan untuk menemukan masalah.

Seperti disebutkan sebelumnya, penunjuk dasar (esp) menunjuk ke teks pesan Anda alih-alih menunjuk ke instruksi.

ba Gunakan perintah untuk mengatur titik henti pada akses memori. Anda mengatur w - titik henti tulis untuk melihat kapan area memori ini ditulis.

0:000> ba w4 003cf7c8

Meskipun Anda menggunakan titik henti akses memori sederhana, Anda dapat membuat titik henti menjadi pernyataan kondisional yang lebih kompleks. Untuk informasi selengkapnya, lihat bp, bu, bm (Set Breakpoint).

Pada menu Beranda, pilih Kembali untuk melakukan perjalanan kembali ke waktu sebelumnya sampai titik henti tercapai.

Pada titik ini, Anda dapat memeriksa tumpukan program untuk melihat kode apa yang aktif.

Cuplikan layar dari garis waktu di debugger yang menampilkan garis waktu akses memori dan jendela stack.

Karena hampir tidak mungkin fungsi wscpy_s() yang disediakan oleh Microsoft memiliki bug kode seperti ini, selidiki lebih lanjut ke dalam tumpukan. Tumpukan menunjukkan bahwa Greeting!main memanggil Greeting!GetCppConGreeting. Dalam sampel kode kecil Anda, Anda dapat membuka kode pada saat ini dan kemungkinan menemukan kesalahan dengan mudah. Tetapi untuk mengilustrasikan teknik yang dapat Anda gunakan dengan program yang lebih besar dan lebih kompleks, Anda menambahkan garis waktu panggilan fungsi.

Garis waktu panggilan fungsi

Pilih + Tambahkan garis waktu dan isi DisplayGreeting!GetCppConGreeting untuk string pencarian fungsi.

Kotak centang Lokasi Mulai dan Lokasi Akhir menunjukkan awal dan akhir panggilan fungsi dalam pelacakan.

Anda dapat menggunakan perintah dx untuk menampilkan objek panggilan fungsi dan melihat bidang TimeStart dan TimeEnd yang sesuai dengan lokasi mulai dan lokasi akhir panggilan fungsi.

dx @$cursession.TTD.Calls("DisplayGreeting!GetCppConGreeting")[0x0]
    EventType        : 0x0
    ThreadId         : 0x6600
    UniqueThreadId   : 0x2
    TimeStart        : 6D:BD [Time Travel]
    SystemTimeStart  : Thursday, October 31, 2019 23:36:05
    TimeEnd          : 6D:742 [Time Travel]
    SystemTimeEnd    : Thursday, October 31, 2019 23:36:05
    Function         : DisplayGreeting!GetCppConGreeting
    FunctionAddress  : 0x615a0
    ReturnAddress    : 0x61746
    Parameters  

Salah satu kotak centang Lokasi Mulai atau Lokasi Akhir atau kedua kotak centang Lokasi Mulai dan Lokasi Akhir harus dipilih.

Cuplikan layar dialog Tambahkan garis waktu baru yang menampilkan penambahan garis waktu Panggilan Fungsi dengan string pencarian fungsi DisplayGreeting! GetCppCongreeting.

Kode Anda tidak rekursif atau reentrant, sehingga mudah untuk ditemukan pada garis waktu ketika metode GetCppConGreeting dipanggil. Panggilan ke GetCppConGreeting juga terjadi pada saat yang sama dengan titik henti Anda dan peristiwa akses memori yang Anda tentukan. Jadi sepertinya Anda sudah mempersempit area kode untuk memeriksa dengan cermat penyebab utama kerusakan aplikasi.

Cuplikan layar garis waktu di debugger yang menampilkan garis waktu akses memori dan jendela Lokal dengan pesan dan buffer yang berisi nilai string yang berbeda.

Menjelajahi eksekusi kode dengan melihat beberapa garis waktu

Meskipun sampel kode kami kecil, teknik menggunakan beberapa garis waktu memungkinkan eksplorasi visual pelacakan perjalanan waktu. Anda dapat melihat seluruh file pelacakan untuk mengajukan pertanyaan, seperti, "Kapan area memori diakses sebelum titik henti ditemui?".

Cuplikan layar dari garis waktu di debugger yang memperlihatkan garis waktu Akses Memori dan jendela Locals.

Kemampuan untuk melihat lebih banyak korelasi dan menemukan hal-hal tak terduga membedakan alat garis waktu dari berinteraksi dengan jejak perjalanan waktu dengan menggunakan perintah baris perintah.

Penanda garis waktu

Bookmark posisi perjalanan waktu penting di WinDbg alih-alih menyalin dan menempelkan posisi secara manual ke Notepad. Penanda buku memudahkan untuk mengamati dengan cepat berbagai posisi dalam rekaman relatif terhadap peristiwa lain dan untuk memberi anotasi.

Anda dapat memberikan nama deskriptif untuk penanda buku.

Cuplikan layar dialog Bookmark Baru memperlihatkan nama contoh untuk panggilan API pertama di aplikasi Tampilkan Salam.

Pilih Tampilkan>Garis Waktu untuk membuka jendela Garis Waktu sehingga Anda bisa mengakses garis waktu Bookmark . Saat Anda mengarahkan mouse ke atas bookmark, nama bookmark akan muncul.

Cuplikan layar dari garis waktu yang menampilkan tiga penanda buku dengan kursor melayang di atas salah satu untuk menampilkan nama penanda buku.

Klik kanan bookmark untuk melakukan perjalanan ke posisi bookmark, mengganti nama bookmark, atau menghapusnya.

Cuplikan layar menu pop-up klik kanan Bookmarks yang menampilkan opsi untuk beralih ke posisi, mengedit, dan menghapus.

Nota

Fitur bookmark tidak tersedia di WinDbg versi 1.2402.24001.0.