Penelusuran Kesalahan Perjalanan Waktu - Contoh Panduan Aplikasi
Lab ini memperkenalkan Time Travel Debugging (TTD), menggunakan program sampel kecil dengan kelemahan kode. TTD digunakan untuk men-debug, mengidentifikasi, dan akar penyebab masalah. Meskipun masalah dalam program kecil ini mudah ditemukan, prosedur umum dapat digunakan pada kode yang lebih kompleks. Prosedur umum ini dapat diringkas sebagai berikut.
- Ambil jejak perjalanan waktu dari program yang gagal.
- Gunakan perintah dx (Ekspresi Model Objek Debugger Tampilan) untuk menemukan peristiwa pengecualian yang disimpan dalam rekaman.
- Gunakan perintah !tt (perjalanan waktu) untuk melakukan perjalanan ke posisi peristiwa pengecualian dalam jejak.
- Dari titik itu dalam satu langkah pelacakan mundur sampai kode yang salah yang dimaksud masuk ke dalam cakupan.
- Dengan kode yang rusak dalam cakupan, lihat nilai lokal dan kembangkan hipotesis variabel yang mungkin berisi nilai yang salah.
- Tentukan alamat memori variabel dengan nilai yang salah.
- Atur titik henti akses memori (ba) pada alamat variabel tersangka menggunakan perintah ba (Break on Access ).
- Gunakan g- untuk menjalankan kembali ke titik akhir akses memori variabel tersangka.
- Lihat apakah lokasi tersebut, atau beberapa instruksi sebelumnya, adalah titik kelemahan kode. Jika demikian, Anda sudah selesai. Jika nilai yang salah berasal dari beberapa variabel lain, atur jeda lain pada titik henti akses pada variabel kedua.
- Gunakan g- untuk menjalankan kembali ke titik terakhir akses memori pada variabel tersangka kedua. Lihat apakah lokasi tersebut atau beberapa instruksi sebelum berisi kelemahan kode. Jika demikian, Anda sudah selesai.
- Ulangi proses ini berjalan kembali hingga kode yang mengatur nilai yang salah yang menyebabkan kesalahan berada.
Meskipun teknik umum yang dijelaskan dalam prosedur ini berlaku untuk serangkaian masalah kode yang luas, ada masalah kode unik yang akan memerlukan pendekatan unik. Teknik yang diilustrasikan dalam panduan harus berfungsi untuk memperluas set alat penelusuran kesalahan Anda dan akan menggambarkan beberapa hal yang mungkin dilakukan dengan jejak TTD.
Tujuan lab
Setelah menyelesaikan lab ini, Anda akan dapat menggunakan prosedur umum dengan jejak perjalanan waktu untuk menemukan masalah dalam kode.
Penyiapan lab
Anda akan memerlukan perangkat keras berikut untuk dapat menyelesaikan lab.
- Laptop atau komputer desktop (host) yang menjalankan Windows 10 atau Windows 11
Anda akan memerlukan perangkat lunak berikut untuk dapat menyelesaikan lab.
- The WinDbg. Untuk informasi tentang menginstal WinDbg, lihat WinDbg - Penginstalan
- Visual Studio untuk membuat sampel kode C++.
Lab ini memiliki tiga bagian berikut.
- Bagian 1: Buat kode sampel
- Bagian 2: Rekam jejak sampel "DisplayGreeting"
- Bagian 3: Menganalisis rekaman file pelacakan untuk mengidentifikasi masalah kode
Bagian 1: Buat kode sampel
Di Bagian 1, Anda akan membuat kode sampel menggunakan Visual Studio.
Membuat aplikasi sampel di Visual Studio
Di Microsoft Visual Studio, klik File>Proyek/Solusi Baru>... dan klik templat Visual C++.
Pilih Aplikasi Konsol Win32.
Berikan nama proyek DisplayGreeting dan klik OK.
Hapus centang pemeriksaan Siklus Hidup Pengembangan Keamanan (SDL).
Klik Selesai.
Tempelkan teks berikut ke panel DisplayGreeting.cpp di Visual Studio.
// DisplayGreeting.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <array> #include <stdio.h> #include <string.h> void GetCppConGreeting(wchar_t* buffer, size_t size) { wchar_t const* const message = L"HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL DEBUGGING!"; wcscpy_s(buffer, size, message); } int main() { std::array <wchar_t, 50> greeting{}; GetCppConGreeting(greeting.data(), sizeof(greeting)); wprintf(L"%ls\n", greeting.data()); return 0; }
Di Visual Studio, klik Properti Proyek>DisplayGreeting. Kemudian klik C/C++ dan Pembuatan Kode.
Atur properti berikut.
Pengaturan Nilai Pemeriksaan Keamanan Nonaktifkan Pemeriksaan Keamanan (/GS-) Pemeriksaan Runtime Dasar Default Catatan
Meskipun pengaturan ini tidak disarankan, dimungkinkan untuk membayangkan skenario di mana seseorang akan menyarankan penggunaan pengaturan ini untuk mempercepat pengkodian atau untuk memfasilitasi lingkungan pengujian tertentu.
Di Visual Studio, klik Bangun>Solusi Build.
Jika semua berjalan dengan baik, jendela build harus menampilkan pesan yang menunjukkan bahwa build berhasil.
Menemukan file aplikasi sampel bawaan
Di Penjelajah Solusi, klik kanan pada proyek DisplayGreeting dan pilih Buka Folder di File explorer.
Navigasikan ke folder Debug yang berisi file exe dan simbol pdb yang sesuai untuk sampel. Misalnya, Anda akan menavigasi ke C:\Projects\DisplayGreeting\Debug, jika itu adalah folder tempat proyek Anda disimpan.
Jalankan aplikasi sampel dengan kelemahan kode
Klik dua kali pada file exe untuk menjalankan aplikasi sampel.
Jika kotak dialog ini muncul, pilih Tutup program
Di bagian berikutnya dari panduan, kita akan merekam eksekusi aplikasi sampel untuk melihat apakah kita dapat menentukan mengapa pengecualian ini terjadi.
Bagian 2: Rekam jejak sampel "DisplayGreeting"
Di Bagian 2, Anda akan merekam jejak sampel aplikasi "DisplayGreeting" yang tidak beres
Untuk meluncurkan aplikasi sampel dan merekam jejak TTD, ikuti langkah-langkah ini. Untuk informasi umum tentang merekam jejak TTD, lihat Penelusuran Kesalahan Perjalanan Waktu - Merekam jejak
Jalankan WinDbg sebagai Administrator, sehingga dapat merekam jejak perjalanan waktu.
Di WinDbg, pilih Mulai Penelusuran kesalahan>File>Luncurkan yang dapat dieksekusi (tingkat lanjut).
Masukkan jalur ke mode pengguna yang dapat dieksekusi yang ingin Anda rekam atau pilih Telusuri untuk menavigasi ke yang dapat dieksekusi. Untuk informasi tentang bekerja dengan menu yang dapat dieksekusi peluncuran di WinDbg, lihat WinDbg - Memulai sesi mode pengguna.
Centang kotak Rekam dengan Penelusuran Kesalahan Perjalanan Waktu untuk merekam jejak saat executable diluncurkan.
Klik Konfigurasikan dan Rekam untuk mulai merekam.
Saat kotak dialog "Konfigurasikan perekaman" muncul, Klik Rekaman untuk meluncurkan executable dan mulai merekam.
Dialog perekaman muncul yang menunjukkan jejak sedang direkam. Tak lama setelah itu, aplikasi mengalami crash.
Klik Tutup Program, untuk menutup kotak dialog "DisplayGreeting telah berhenti berfungsi".
Ketika program crash, file pelacakan akan ditutup dan ditulis ke disk.
Debugger akan secara otomatis membuka file pelacakan dan mengindeksnya. Pengindeksan adalah proses yang memungkinkan penelusuran kesalahan file pelacakan yang efisien. Proses pengindeksan ini akan memakan waktu lebih lama untuk file pelacakan yang lebih besar.
(5120.2540): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: D:0 [Unindexed] Index !index Indexed 10/22 keyframes Indexed 20/22 keyframes Indexed 22/22 keyframes Successfully created the index in 755ms.
Catatan
Keyframe adalah lokasi dalam jejak yang digunakan untuk pengindeksan. Keyframe dihasilkan secara otomatis. Jejak yang lebih besar akan berisi lebih banyak keyframe.
Pada titik ini Anda berada di awal file pelacakan dan siap untuk melakukan perjalanan maju dan mundur ke waktu.
Sekarang setelah Anda merekam jejak TTD, Anda dapat memutar ulang jejak kembali atau bekerja dengan file pelacakan, misalnya membagikannya dengan rekan kerja. Untuk informasi selengkapnya tentang bekerja dengan file pelacakan, lihat Penelusuran Kesalahan Perjalanan Waktu - Bekerja dengan File Pelacakan
Di bagian berikutnya dari lab ini kita akan menganalisis file jejak untuk menemukan masalah dengan kode kita.
Bagian 3: Menganalisis rekaman file pelacakan untuk mengidentifikasi masalah kode
Di Bagian 3, Anda akan menganalisis rekaman file jejak untuk mengidentifikasi masalah kode.
Mengonfigurasi Lingkungan WinDbg
Tambahkan lokasi simbol lokal Anda ke jalur simbol dan muat ulang simbol, dengan mengetik perintah berikut.
.sympath+ C:\MyProjects\DisplayGreeting\Debug .reload
Tambahkan lokasi kode lokal Anda ke jalur sumber dengan mengetik perintah berikut.
.srcpath+ C:\MyProjects\DisplayGreeting\DisplayGreeting
Agar dapat melihat status tumpukan dan variabel lokal, pada pita WinDbg, pilih Tampilan dan Lokal dan Tampilan dan Tumpukan. Atur jendela untuk memungkinkan Anda melihatnya, kode sumber, dan jendela perintah secara bersamaan.
Pada pita WinDbg, pilih Sumber dan File Sumber Terbuka. Temukan file DisplayGreeting.cpp dan buka.
Memeriksa pengecualian
Ketika file pelacakan dimuat, file tersebut akan menampilkan informasi bahwa terjadi pengecualian.
2fa8.1fdc): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68ef8100 ebx=00000000 ecx=77a266ac edx=69614afc esi=6961137c edi=004da000 eip=77a266ac esp=0023f9b4 ebp=0023fc04 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:0023fac0=00000000
Gunakan perintah dx untuk mencantumkan semua peristiwa dalam rekaman. Peristiwa pengecualian tercantum dalam peristiwa.
0:000> dx -r1 @$curprocess.TTD.Events ... [0x2c] : Module Loaded at position: 9967:0 [0x2d] : Exception at 9BDC:0 [0x2e] : Thread terminated at 9C43:0 ...
Catatan
Dalam panduan ini tiga periode digunakan untuk menunjukkan bahwa output asing dihapus.
Klik peristiwa Pengecualian untuk menampilkan informasi tentang peristiwa TTD tersebut.
0:000> dx -r1 @$curprocess.TTD.Events[17] @$curprocess.TTD.Events[17] : Exception at 68:0 Type : Exception Position : 68:0 [Time Travel] Exception : Exception of type Hardware at PC: 0X540020
Klik bidang Pengecualian untuk menelusuri lebih lanjut data pengecualian.
0:000> dx -r1 @$curprocess.TTD.Events[17].Exception @$curprocess.TTD.Events[17].Exception : Exception of type Hardware at PC: 0X540020 Position : 68:0 [Time Travel] Type : Hardware ProgramCounter : 0x540020 Code : 0xc0000005 Flags : 0x0 RecordAddress : 0x0
Data pengecualian menunjukkan bahwa ini adalah kesalahan Perangkat Keras yang dilemparkan oleh CPU. Ini juga menyediakan kode pengecualian 0xc0000005 yang menunjukkan bahwa ini adalah pelanggaran akses. Ini biasanya menunjukkan bahwa kami mencoba menulis ke memori yang tidak dapat kita akses.
Klik tautan [Perjalanan Waktu] di peristiwa pengecualian untuk berpindah ke posisi tersebut di pelacakan.
0:000> dx @$curprocess.TTD.Events[17].Exception.Position.SeekTo() Setting position: 68:0 @$curprocess.TTD.Events[17].Exception.Position.SeekTo() (16c8.1f28): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 68:0 eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c 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 ??
Catatan dalam output ini adalah bahwa tumpukan dan penunjuk dasar menunjuk ke dua alamat yang sangat berbeda.
esp=00effe4c ebp=00520055
Ini dapat menunjukkan bahwa kerusakan tumpukan - mungkin fungsi yang dikembalikan dan kemudian merusak tumpukan. Untuk memvalidasi ini, kita perlu melakukan perjalanan kembali sebelum status CPU rusak dan melihat apakah kita dapat menentukan kapan kerusakan tumpukan terjadi.
Memeriksa variabel lokal dan mengatur titik henti kode
Pada titik kegagalan dalam pelacakan, biasanya berakhir beberapa langkah setelah penyebab sebenarnya dalam kode penanganan kesalahan. Dengan perjalanan waktu kita dapat kembali instruksi pada satu waktu, untuk menemukan akar penyebab sebenarnya.
Dari pita Beranda gunakan perintah Langkah Ke Belakang untuk mengembalikan tiga instruksi. Saat Anda melakukan ini, terus periksa tumpukan dan jendela memori.
Jendela perintah akan menampilkan posisi perjalanan waktu dan daftar saat Anda mundur tiga instruksi.
0:000> t- Time Travel Position: 67:40 eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c 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: 67:3F eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=0019193d esp=00effe48 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+0x4d: 0019193d c3 0:000> t- Time Travel Position: 67:39 eax=0000004c ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00191935 esp=00effd94 ebp=00effe44 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 DisplayGreeting!main+0x45:
Catatan
Dalam panduan ini, output perintah menunjukkan perintah yang dapat digunakan alih-alih opsi Menu UI untuk memungkinkan pengguna dengan preferensi penggunaan baris perintah untuk menggunakan perintah baris perintah.
Pada titik ini dalam pelacakan tumpukan dan penunjuk dasar kita memiliki nilai yang lebih masuk akal, sehingga tampaknya kita telah semakin dekat dengan titik dalam kode tempat kerusakan terjadi.
esp=00effd94 ebp=00effe44
Yang juga menarik adalah bahwa jendela lokal berisi nilai dari aplikasi target kami dan jendela kode sumber menyoroti baris kode yang siap untuk dieksekusi pada titik ini dalam jejak.
Untuk menyelidiki lebih lanjut, kita dapat membuka jendela memori untuk melihat konten di dekat alamat memori pointer dasar 0x00effe44.
Untuk menampilkan karakter ASCII terkait, dari pita Memori, pilih Teks lalu ASCII.
Alih-alih pointer dasar yang menunjuk ke instruksi, itu menunjuk ke teks pesan kami. Jadi ada sesuatu yang tidak benar di sini, ini mungkin dekat dengan titik waktu bahwa kita telah merusak tumpukan. Untuk menyelidiki lebih lanjut, kami akan menetapkan titik henti.
Catatan
Dalam sampel yang sangat kecil ini akan sangat mudah untuk hanya melihat dalam kode, tetapi jika ada ratusan baris kode dan puluhan subroutine teknik yang dijelaskan di sini dapat digunakan untuk mengurangi waktu yang diperlukan untuk menemukan masalah.
TTD dan titik henti
Menggunakan titik henti adalah pendekatan umum untuk menjeda eksekusi kode pada beberapa peristiwa yang menarik. TTD memungkinkan Anda untuk mengatur titik henti dan melakukan perjalanan kembali ke waktu hingga titik henti tersebut terpukul setelah jejak direkam. Kemampuan untuk memeriksa status proses setelah masalah terjadi, untuk menentukan lokasi terbaik untuk titik henti, memungkinkan alur kerja penelusuran kesalahan tambahan yang unik untuk TTD.
Titik henti akses memori
Anda dapat mengatur titik henti yang diaktifkan saat lokasi memori diakses. Gunakan perintah ba (putuskan akses), dengan sintaks berikut.
ba <access> <size> <address> {options}
Opsi | Deskripsi |
---|---|
e |
jalankan (ketika CPU mengambil instruksi dari alamat) |
r |
baca/tulis (saat CPU membaca atau menulis ke alamat) |
w |
tulis (ketika CPU menulis ke alamat) |
Perhatikan bahwa Anda hanya dapat mengatur empat titik henti data pada waktu tertentu dan terserah Anda untuk memastikan bahwa Anda menyelaraskan data dengan benar atau Anda tidak akan memicu titik henti (kata harus berakhir di alamat yang dapat dibagi dengan 2, kata sandi harus dapat dibagi dengan 4, dan quadwords sebesar 0 atau 8).
Mengatur pemutusan pada titik henti akses memori untuk penunjuk dasar
Pada titik ini dalam jejak kami ingin mengatur titik henti pada akses memori tulis ke penunjuk dasar - ebp yang dalam contoh kami adalah 00effe44. Untuk melakukan ini, gunakan perintah ba menggunakan alamat yang ingin kita pantau. Kami ingin memantau penulisan selama empat byte, jadi kami menentukan w4.
0:000> ba w4 00effe44
Pilih Tampilkan lalu Titik Henti untuk mengonfirmasi bahwa titik henti diatur sebagaimana dimaksud.
Dari menu Beranda, pilih Kembali untuk melakukan perjalanan kembali tepat waktu hingga titik henti terbentur.
0:000> g- Breakpoint 0 hit Time Travel Position: 5B:92 eax=0000000f ebx=003db000 ecx=00000000 edx=00cc1a6c esi=00d41046 edi=0053fde8 eip=00d4174a esp=0053fcf8 ebp=0053fde8 iopl=0 nv up ei pl nz ac pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216 DisplayGreeting!DisplayGreeting+0x3a: 00d4174a c745e000000000 mov dword ptr [ebp-20h],0 ss:002b:0053fdc8=cccccccc
Pilih Tampilkan lalu Lokal. Di jendela lokal kita dapat melihat bahwa variabel tujuan hanya memiliki bagian dari pesan, sementara sumbernya berisi semua teks. Informasi ini mendukung gagasan bahwa tumpukan rusak.
Pada titik ini kita dapat memeriksa tumpukan program untuk melihat kode apa yang aktif. Dari pita Tampilan pilih Tumpukan.
Karena sangat tidak mungkin bahwa fungsi Microsoft yang disediakan wscpy_s() akan memiliki bug kode seperti ini, kita melihat lebih jauh di tumpukan. Tumpukan menunjukkan bahwa Salam!panggilan utama Salam! GetCppCongreeting. Dalam sampel kode kami yang sangat kecil, kami hanya dapat membuka kode pada saat ini dan kemungkinan menemukan kesalahan dengan cukup mudah. Tetapi untuk menggambarkan teknik yang dapat digunakan dengan program yang lebih besar dan lebih kompleks, kami akan mengatur titik henti baru untuk menyelidiki lebih lanjut.
Mengatur pemutusan pada titik henti akses untuk fungsi GetCppConGreeting
Gunakan jendela titik henti untuk menghapus titik henti yang ada dengan mengklik kanan titik henti yang ada dan memilih Hapus.
Tentukan alamat DisplayGreeting! Fungsi GetCppConGreeting menggunakan perintah dx .
0:000> dx &DisplayGreeting!GetCppConGreeting &DisplayGreeting!GetCppConGreeting : 0xb61720 [Type: void (__cdecl*)(wchar_t *,unsigned int)] [Type: void __cdecl(wchar_t *,unsigned int)]
Gunakan perintah ba untuk mengatur titik henti pada akses memori. Karena fungsi hanya akan dibaca dari memori untuk eksekusi, kita perlu mengatur r - read breakpoint.
0:000> ba r4 b61720
Konfirmasikan bahwa titik henti Baca Perangkat Keras aktif di jendela titik henti.
Saat kita bertanya-tanya tentang ukuran string salam, kita akan mengatur jendela pengawasan untuk menampilkan nilai sizeof (salam). Dari pita Tampilan, pilih Tonton dan sediakan ukurandari(salam).
Pada menu Perjalanan Waktu, gunakan Perjalanan waktu untuk memulai atau menggunakan
!tt 0
perintah untuk berpindah ke awal jejak.0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000
Pada menu Beranda, pilih Buka atau gunakan
g
perintah , untuk maju dalam kode hingga titik henti tertembak.0:000> g Breakpoint 2 hit Time Travel Position: 4B:1AD eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61721 esp=00ddf7a4 ebp=00ddf864 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!GetCppConGreeting+0x1: 00b61721 8bec mov ebp,esp
Pada menu Beranda, pilih Langkah Mundur atau gunakan
g-u
perintah untuk mundur satu langkah.0:000> g-u Time Travel Position: 4B:1AA eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61917 esp=00ddf7ac ebp=00ddf864 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!main+0x27: 00b61917 e8def7ffff call DisplayGreeting!ILT+245(?GetCppConGreetingYAXPA_WIZ) (00b610fa)
Sepertinya kita telah menemukan akar penyebabnya. Panjang array salam yang kami deklarasikan adalah 50 karakter, sedangkan sizeof(greeting) yang kita berikan ke GetCppConGreeting 0x64, 100).
Saat melihat masalah ukuran lebih lanjut, kami juga melihat bahwa panjang pesan adalah 75 karakter, 76 termasuk akhir karakter string.
HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL DEBUGGING!
Salah satu cara untuk memperbaiki kode adalah dengan memperluas ukuran array karakter menjadi 100.
std::array <wchar_t, 100> greeting{};
Dan kita juga perlu mengubah sizeof (salam) menjadi ukuran (salam) dalam baris kode ini.
GetCppConGreeting(greeting.data(), size(greeting));
Untuk memvalidasi perbaikan ini, kita dapat mengkompilasi ulang kode dan mengonfirmasi bahwa kode berjalan tanpa kesalahan.
Mengatur titik henti menggunakan jendela sumber
Cara alternatif untuk melakukan penyelidikan ini adalah dengan mengatur titik henti dengan mengklik baris kode apa pun. Misalnya mengklik di sisi kanan baris definisi std:array di jendela sumber akan mengatur titik henti di sana.
Pada menu Perjalanan Waktu, gunakan perintah Perjalanan waktu untuk memulai untuk berpindah ke awal pelacakan.
0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000
Pada Pita Beranda klik Masuk untuk melakukan perjalanan kembali hingga titik henti ditemui.
Breakpoint 0 hit Time Travel Position: 5B:AF eax=0000000f ebx=00c20000 ecx=00000000 edx=00000000 esi=013a1046 edi=00effa60 eip=013a17c1 esp=00eff970 ebp=00effa60 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!DisplayGreeting+0x41: 013a17c1 8bf4 mov esi,esp
Mengatur pemutusan pada titik henti akses untuk variabel salam
Cara alternatif lain untuk melakukan penyelidikan ini, adalah dengan mengatur titik henti pada variabel tersangka dan memeriksa kode apa yang mengubahnya. Misalnya, untuk mengatur titik henti pada variabel salam dalam metode GetCppConGreeting, gunakan prosedur ini.
Bagian panduan ini mengasumsikan bahwa Anda masih berada di titik henti dari bagian sebelumnya.
Dari Tampilan lalu Lokal. Di jendela lokal, salam tersedia dalam konteks saat ini, sehingga kita akan dapat menentukan lokasi memorinya.
Gunakan perintah dx untuk memeriksa array salam.
0:000> dx &greeting &greeting : 0xddf800 [Type: std::array<wchar_t,50> *] [+0x000] _Elems : "꽘棶檙瞝???" [Type: wchar_t [50]]
Dalam jejak ini, salam terletak dalam memori di ddf800.
Gunakan jendela titik henti untuk menghapus titik henti yang ada dengan mengklik kanan titik henti yang ada dan memilih Hapus.
Atur titik henti dengan perintah ba menggunakan alamat memori yang ingin kita pantau untuk akses tulis.
ba w4 ddf800
Pada menu Perjalanan Waktu, gunakan perintah Perjalanan waktu untuk memulai untuk berpindah ke awal pelacakan.
0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00 cmp dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000
Pada menu Beranda, pilih Buka untuk melanjutkan ke titik pertama akses memori array salam.
0:000> g- Breakpoint 0 hit Time Travel Position: 5B:9C eax=cccccccc ebx=002b1000 ecx=00000000 edx=68d51a6c esi=013a1046 edi=001bf7d8 eip=013a1735 esp=001bf6b8 ebp=001bf7d8 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 DisplayGreeting!GetCppConGreeting+0x25: 013a1735 c745ec04000000 mov dword ptr [ebp-14h],4 ss:002b:001bf7c4=cccccccc
Atau, kita bisa melakukan perjalanan ke akhir jejak dan bekerja secara terbalik melalui kode untuk menemukan titik terakhir dalam jejak tempat lokasi memori array ditulis.
Gunakan TTD. Objek memori untuk melihat akses memori
Cara lain untuk menentukan titik apa dalam memori jejak yang telah diakses, adalah dengan menggunakan TTD. Objek memori dan perintah dx.
Gunakan perintah dx untuk memeriksa array salam.
0:000> dx &greeting &greeting : 0xddf800 [Type: std::array<wchar_t,50> *] [+0x000] _Elems : "꽘棶檙瞝???" [Type: wchar_t [50]]
Dalam jejak ini, salam terletak dalam memori di ddf800.
Gunakan perintah dx untuk melihat empat byte dalam memori yang dimulai dari alamat tersebut dengan akses tulis baca.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw") @$cursession.TTD.Memory(0x1bf7d0,0x1bf7d4, "rw") [0x0] [0x1] [0x2] [0x3] [0x4] [0x5] [0x6] [0x7] [0x8] [0x9] [0xa] ...
Klik salah satu kemunculan untuk menampilkan informasi lebih lanjut tentang kemunculan akses memori tersebut.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5] @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5] EventType : MemoryAccess ThreadId : 0x710 UniqueThreadId : 0x2 TimeStart : 27:3C1 [Time Travel] TimeEnd : 27:3C1 [Time Travel] AccessType : Write IP : 0x6900432f Address : 0xddf800 Size : 0x4 Value : 0xddf818
Klik [Perjalanan Waktu] untuk memposisikan jejak pada titik waktu.
0:000> dx @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() (1e5c.710): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 27:3C1 eax=00ddf81c ebx=00fa2000 ecx=00ddf818 edx=ffffffff esi=00000000 edi=00b61046 eip=6900432f esp=00ddf804 ebp=00ddf810 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 ucrtbased!_register_onexit_function+0xf: 6900432f 51 push ecx
Jika kita tertarik pada kemunculan terakhir akses memori baca/tulis dalam jejak, kita dapat mengklik item terakhir dalam daftar atau menambahkan . Fungsi last() ke akhir perintah dx.
0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw").Last() @$cursession.TTD.Memory(0xddf800,0xddf804, "rw").Last() EventType : MemoryAccess ThreadId : 0x710 UniqueThreadId : 0x2 TimeStart : 53:100E [Time Travel] TimeEnd : 53:100E [Time Travel] AccessType : Read IP : 0x690338e4 Address : 0xddf802 Size : 0x2 Value : 0x45
Kita kemudian dapat mengklik [Perjalanan Waktu] untuk pindah ke posisi tersebut dalam jejak dan melihat lebih jauh eksekusi kode pada saat itu, menggunakan teknik yang dijelaskan sebelumnya di lab ini.
Untuk informasi selengkapnya tentang TTD. Objek memori, lihat TTD. Objek Memori.
Ringkasan
Dalam sampel yang sangat kecil ini masalah dapat ditentukan dengan melihat beberapa baris kode, tetapi dalam program yang lebih besar teknik yang disajikan di sini dapat digunakan untuk mengurangi waktu yang diperlukan untuk menemukan masalah.
Setelah jejak direkam, langkah-langkah pelacakan dan repro dapat dibagikan, dan masalahnya akan dapat direproduksi sesuai permintaan pada PC apa pun.
Lihat Juga
Penelusuran Kesalahan Perjalanan Waktu - Gambaran Umum
Penelusuran Kesalahan Perjalanan Waktu - Perekaman
Penelusuran Kesalahan Perjalanan Waktu - Memutar ulang pelacakan
Penelusuran Kesalahan Perjalanan Waktu - Bekerja dengan file pelacakan