Mengaktifkan Penelusuran Kesalahan Setelah Kematian
Pengecualian dan Titik Henti
Kesalahan aplikasi yang paling umum disebut pengecualian. Ini termasuk pelanggaran akses, kesalahan pembagian dengan nol, kelebihan numerik, pengecualian CLR, dan banyak jenis kesalahan lainnya. Aplikasi juga dapat menyebabkan gangguan titik henti. Ini terjadi ketika Windows tidak dapat menjalankan aplikasi (misalnya, ketika modul yang diperlukan tidak dapat dimuat) atau ketika titik henti ditemui. Titik henti dapat dimasukkan ke dalam kode oleh debugger, atau dipanggil melalui fungsi seperti DebugBreak.
Penanganan Pengecualian Prioritas
Berdasarkan nilai konfigurasi dan debugger mana yang aktif, Windows menangani kesalahan mode pengguna dengan berbagai cara. Urutan berikut menunjukkan prioritas yang digunakan untuk penanganan kesalahan mode pengguna:
Jika debugger mode pengguna saat ini terpasang pada proses yang mengalami kesalahan, semua kesalahan akan memicu target untuk mengakses debugger ini.
Selama debugger mode pengguna dilampirkan, tidak ada metode penanganan kesalahan lain yang akan digunakan -- bahkan jika perintah gn (Go With Exception Not Handled) digunakan.
Jika tidak ada debugger mode pengguna yang dilampirkan dan kode yang dijalankan memiliki rutinitas penanganan pengecualian sendiri (misalnya, coba - kecuali), rutinitas penanganan pengecualian ini akan mencoba menangani kesalahan.
Jika tidak ada debugger mode pengguna yang terpasang, dan Windows memiliki koneksi debugging kernel terbuka, dan kesalahannya adalah gangguan titik henti, Windows akan mencoba menghubungi debugger kernel.
Koneksi debugging kernel harus dibuka selama proses boot Windows. Jika Anda ingin mencegah gangguan mode pengguna masuk ke debugger kernel, Anda dapat menggunakan utilitas KDbgCtrl dengan parameter -du. Untuk detail tentang cara mengonfigurasi koneksi penelusuran kesalahan kernel dan cara menggunakan KDbgCtrl, lihat Mempersiapkan untuk Debugging.
Dalam debugger kernel, Anda dapat menggunakan gh (Go With Exception Handled) untuk mengabaikan kesalahan dan terus menjalankan target. Anda dapat menggunakan gn (Go With Exception Not Handled) untuk melewati debugger kernel dan meneruskan ke langkah 4.
Jika kondisi di langkah 1, 2, dan 3 tidak berlaku, Windows akan mengaktifkan alat penelusuran kesalahan yang dikonfigurasi dalam nilai registri AeDebug. Program apa pun dapat dipilih terlebih dahulu sebagai alat untuk digunakan dalam situasi ini. Program yang dipilih disebut sebagai debugger postmortem .
Jika kondisi dalam langkah 1, 2, dan 3 tidak berlaku, dan tidak ada debugger postmortem yang terdaftar, Windows Error Reporting (WER) menampilkan pesan dan memberikan solusi jika ada yang tersedia. WER juga menulis file cadangan memori jika nilai yang sesuai diatur dalam Registri. Untuk informasi selengkapnya, lihat Menggunakan WER dan Mengumpulkan User-Mode Dump.
Fungsi DebugBreak
Jika debugger postmortem telah diinstal, Anda dapat dengan sengaja masuk ke debugger dari aplikasi mode pengguna dengan memanggil fungsi DebugBreak.
Bagian ini menjelaskan cara mengonfigurasi alat seperti WinDbg sebagai debugger postmortem. Setelah dikonfigurasi, debugger postmortem akan dimulai secara otomatis setiap kali aplikasi mengalami crash.
Kunci Registri Post Mortem Debugger
Windows Error Reporting (WER) membuat proses debugger postmortem dengan menggunakan nilai-nilai yang ditetapkan dalam kunci registri AeDebug.
HKLM\Perangkat Lunak\Microsoft\Windows NT\CurrentVersion\AeDebug
Ada dua nilai registri utama yang penting, Debugger dan Auto . Nilai registri Debugger menyediakan baris perintah untuk debugger postmortem. Nilai registri Auto menentukan apakah debugger postmortem dimulai secara otomatis, atau jika kotak pesan konfirmasi disajikan terlebih dahulu.
Debugger (REG_SZ)
Nilai REG_SZ ini menentukan debugger yang akan menangani penelusuran kesalahan pascamortem.
Jalur lengkap ke debugger harus dicantumkan kecuali debugger terletak di direktori yang berada di jalur default.
Baris perintah dihasilkan dari string Debugger melalui pemanggilan gaya printf yang menyertakan 3 parameter. Meskipun urutannya tetap, tidak ada persyaratan untuk menggunakan salah satu atau semua parameter yang tersedia.
DWORD (%ld) - ID proses proses target.
DWORD (%ld) - Penanganan Aktivitas diduplikasi ke dalam proses debugger postmortem. Jika debugger postmortem memberi sinyal peristiwa, WER akan melanjutkan proses target tanpa menunggu debugger postmortem dihentikan. Peristiwa hanya boleh diberi sinyal jika masalah telah diselesaikan. Jika debugger postmortem berakhir tanpa memberi sinyal peristiwa, WER melanjutkan pengumpulan informasi tentang proses target.
void* (%p) - Alamat struktur JIT_DEBUG_INFO yang dialokasikan di ruang alamat proses target. Struktur berisi informasi dan konteks pengecualian tambahan.
Auto (REG_SZ) Nilai REG_SZ ini selalu 0 atau 1.
Jika Auto diatur ke 0, sebuah kotak konfirmasi ditampilkan sebelum proses debugging postmortem dimulai.
Jika Otomatis diatur ke 1, debugger postmortem segera dibuat.
Ketika Anda mengedit registri secara manual, lakukan dengan sangat hati-hati, karena perubahan yang tidak tepat pada registri mungkin tidak memungkinkan Windows untuk melakukan booting.
Contoh Penggunaan Baris Perintah
Banyak debugger postmortem menggunakan baris perintah yang mencakup sakelar -p dan -e untuk menunjukkan bahwa parameter tersebut adalah PID dan Acara (masing-masing). Misalnya, menginstal WinDbg melalui windbg.exe -I
membuat nilai berikut:
Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1
Ada fleksibilitas dalam bagaimana parameter %ld %ld %p WER dapat digunakan. Misalnya. tidak ada persyaratan untuk menentukan opsi apa pun di sekitar atau di antara parameter WER. Misalnya, menginstal Windows Sysinternals ProcDump menggunakan procdump.exe -i
membuat nilai berikut tanpa sakelar antara parameter %ld %ld %p WER:
Debugger = "<Path>\procdump.exe" -accepteula -j "c:\Dumps" %ld %ld %p
Auto = 1
Debugger 32 dan 64 bit
Pada platform 64-bit, nilai registri Debugger (REG_SZ) dan Auto (REG_SZ) didefinisikan secara individual untuk aplikasi 64-bit dan 32-bit. Kunci Windows tambahan pada Windows (WOW) digunakan untuk menyimpan nilai debugging post mortem aplikasi 32 bit.
HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Pada platform 64-bit, gunakan debugger pasca-mortem 32-bit untuk proses 32-bit dan debugger 64-bit untuk proses 64-bit. Ini menghindari debugger 64-bit yang berfokus pada utas WOW64, alih-alih utas 32-bit, dalam proses 32-bit.
Untuk banyak debugger postmortem, termasuk Debugging Tools untuk debugger postmortem Windows, ini melibatkan menjalankan perintah penginstalan dua kali; sekali dengan versi x86 dan sekali dengan versi x64. Misalnya, untuk menggunakan WinDbg sebagai debugger postmortem interaktif, perintah windbg.exe -I
akan dijalankan dua kali, sekali untuk setiap versi.
Penginstalan 64-bit:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
Ini memperbarui kunci registri dengan nilai-nilai ini.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld –g
Penginstalan 32-bit:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I
Ini memperbarui kunci registri dengan nilai-nilai ini.
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -p %ld -e %ld –g
Alat Debugging untuk Windows semuanya mendukung pengaturan sebagai debugger postmortem. Perintah instal bermakna agar proses di-debug secara interaktif.
WinDbg
Untuk mengatur debugger postmortem ke WinDbg, jalankan windbg -I
. (I
harus dikapitalisasi.) Perintah ini akan menampilkan pesan keberhasilan atau kegagalan setelah digunakan. Untuk bekerja dengan aplikasi 32 dan 64 bit, jalankan perintah untuk debugger 64 dan 32.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I
Ini adalah bagaimana entri registri AeDebug akan dikonfigurasi saat windbg -I
dijalankan.
Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1
Dalam contoh, <Path> adalah direktori tempat debugger berada.
Parameter -p dan -e melewati ID Proses dan Peristiwa, seperti yang dibahas sebelumnya.
-g meneruskan perintah g (Go) ke WinDbg dan melanjutkan eksekusi dari instruksi saat ini.
Catatan Ada masalah signifikan saat melewati perintah g (Go). Masalah dengan pendekatan ini, adalah bahwa pengecualian tidak selalu berulang, biasanya, karena kondisi sementara yang tidak lagi ada ketika kode dimulai ulang. Untuk informasi selengkapnya tentang masalah ini, lihat .jdinfo (Gunakan JIT_DEBUG_INFO).
Untuk menghindari masalah ini, gunakan .jdinfo atau .dump /j. Pendekatan ini memungkinkan debugger berada dalam konteks kegagalan kode yang menarik. Untuk informasi selengkapnya, lihat Debugging Just In Time (JIT) yang dibahas kemudian dalam topik ini.
CDB
Untuk mengatur debugger postmortem ke CDB, jalankan cdb -iae (Instal AeDebug) atau cdb -iaecKeyString (Instal AeDebug dengan Perintah).
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iae
Ketika parameter -iaec digunakan, KeyString menentukan string yang akan ditambahkan ke akhir baris perintah, yang digunakan untuk meluncurkan debugger postmortem. Jika KeyString berisi spasi, keyString harus diapit dalam tanda kutip.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iaec [KeyString]
Perintah ini tidak menampilkan apa pun jika berhasil, dan pesan kesalahan jika gagal.
NTSD
Untuk mengatur debugger postmortem ke NTSD, jalankan ntsd -iae (Instal AeDebug) atau ntsd -iaecKeyString (Instal AeDebug dengan Perintah).
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iae
Ketika parameter -iaec digunakan, KeyString menentukan string yang akan ditambahkan ke akhir baris perintah untuk meluncurkan debugger postmortem. Jika KeyString berisi spasi, maka harus diapit dalam tanda kutip.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iaec [KeyString]
Perintah ini tidak menampilkan apa pun jika berhasil, dan akan menampilkan kesalahan di jendela konsol baru jika gagal.
Catatan Karena parameter -p %ld -e %ld -g selalu muncul terlebih dahulu pada baris perintah debugger postmortem, Anda tidak boleh menggunakan sakelar -iaec untuk menentukan parameter -server karena -server tidak akan berfungsi kecuali muncul terlebih dahulu pada baris perintah. Untuk menginstal debugger postmortem yang menyertakan parameter ini, Anda harus mengedit registri secara manual.
Jika Visual Studio telah diinstal, vsjitdebugger.exe akan didaftarkan sebagai debugger post mortem. Visual Studio JIT Debugger ingin proses di-debug secara interaktif.
Debugger = "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld
Jika Visual Studio diperbarui atau diinstal ulang, entri ini akan ditulis ulang, menimpa kumpulan nilai alternatif apa pun.
Utilitas Windows Sysinternals ProcDump juga dapat digunakan untuk pengambilan dump pascamortem. Untuk informasi selengkapnya tentang menggunakan dan mengunduh ProcDump, lihat ProcDump.
Seperti perintah .dump WinDbg, ProcDump dapat mengambil dump dari crash secara non-interaktif. Pengambilan dapat terjadi dalam sesi sistem Windows apa pun.
ProcDump keluar ketika pengambilan file cadangan selesai, WER kemudian melaporkan kegagalan dan proses kesalahan dihentikan.
Gunakan procdump -i
untuk menginstal ProcDump dan -u untuk meng-uninstall ProcDump untuk debugging post mortem 32 dan 64 bit.
<Path>\procdump.exe -i
Perintah pemasangan dan pelepasangan menghasilkan nilai registri yang dimodifikasi ketika berhasil, dan kesalahan ketika gagal.
Opsi baris perintah ProcDump dalam registri diatur ke:
Debugger = <Path>\ProcDump.exe -accepteula -j "<DumpFolder>" %ld %ld %p
ProcDump menggunakan semua 3 parameter - PID, Peristiwa, dan JIT_DEBUG_INFO. Untuk informasi selengkapnya tentang parameter JIT_DEBUG_INFO, lihat Debugging Just In Time (JIT) di bawah ini.
Ukuran dump yang diambil secara default adalah Mini (proses/threads/handles/modul/ruang alamat) jika tidak ada opsi ukuran yang diset, MiniPlus (Mini plus halaman MEM_PRIVATE) dengan pengaturan -mp, atau Penuh (semua memori - setara dengan ".dump /mA") dengan pengaturan -ma.
Untuk sistem dengan ruang drive yang memadai, tangkapan Penuh (-ma) disarankan.
Gunakan -ma dengan opsi -i untuk menentukan pengambilan semua memori. Secara opsional, berikan jalur untuk file cadangan.
<Path>\procdump.exe -ma -i c:\Dumps
Untuk sistem dengan ruang drive yang terbatas, disarankan menggunakan capture MiniPlus (-mp).
<Path>\procdump.exe -mp -i c:\Dumps
Folder untuk menyimpan file cadangan bersifat opsional. Defaultnya adalah folder saat ini. Folder harus diamankan dengan ACL yang sama atau lebih baik daripada apa yang digunakan untuk C:\Windows\Temp. Untuk informasi selengkapnya tentang mengelola keamanan yang terkait dengan folder, lihat Keamanan Selama Debugging Postmortem.
Untuk menghapus instalan ProcDump sebagai debugger postmortem, dan memulihkan pengaturan sebelumnya, gunakan opsi -u (Hapus instalasi).
<Path>\procdump.exe -u
Untuk informasi tambahan tentang ProcDump, lihat ProcDump dan Windows SysInternals Administrator's Reference oleh Mark Russinovich dan Aaron Margosis, yang diterbitkan oleh Microsoft Press.
Mengatur Konteks untuk Aplikasi yang Bermasalah
Seperti yang dibahas sebelumnya, sangat diinginkan untuk mengatur konteks pada pengecualian yang menyebabkan terjadinya crash dengan menggunakan parameter JIT_DEBUG_INFO. Untuk informasi selengkapnya tentang ini, lihat .jdinfo (Gunakan JIT_DEBUG_INFO).
Alat Pencarian Bug untuk Windows
Contoh ini menunjukkan cara mengedit registri untuk menjalankan perintah awal (-c) yang menggunakan perintah .jdinfo <alamat> untuk menampilkan informasi pengecualian tambahan, dan mengubah konteks ke lokasi pengecualian (mirip dengan bagaimana .ecxr digunakan mengatur konteks ke rekaman pengecualian).
Debugger = "<Path>\windbg.exe -p %ld -e %ld -c ".jdinfo 0x%p"
Auto = 1
Parameter %p adalah alamat struktur JIT_DEBUG_INFO di ruang alamat proses target. Parameter %p telah ditambahkan sebelumnya dengan 0x sehingga ditafsirkan sebagai nilai hex. Untuk informasi selengkapnya, lihat .jdinfo (Gunakan JIT_DEBUG_INFO).
Untuk men-debug campuran aplikasi 32-bit dan 64-bit, konfigurasikan kunci registri 32-bit dan 64-bit (seperti dijelaskan di atas), lalu atur jalur yang tepat ke lokasi WinDbg.exe64-bit dan 32-bit.
Membuat file cadangan menggunakan .dump
Untuk mengambil file cadangan setiap kali kegagalan terjadi yang menyertakan data JIT_DEBUG_INFO, gunakan alamat .dump /j <>.
<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd"
Gunakan opsi /u untuk menghasilkan nama file unik untuk memungkinkan beberapa file cadangan dibuat secara otomatis. Untuk informasi selengkapnya tentang opsi, lihat, .dump (Buat File Cadangan).
Dump yang dibuat akan menyimpan data JITDEBUG_INFO sebagai konteks pengecualian bawaan. Alih-alih menggunakan .jdinfo untuk melihat informasi pengecualian dan mengatur konteks, gunakan .exr -1 untuk menampilkan rekaman pengecualian dan .ecxr untuk mengatur konteks. Untuk informasi selengkapnya, lihat .exr (Catatan Pengecualian Tampilan) dan .ecxr (Tampilkan Catatan Konteks Pengecualian).
Pelaporan Kesalahan Windows - q / qd
Cara sesi debug berakhir menentukan apakah Pelaporan Kesalahan Windows melaporkan kegagalan.
Jika sesi debug dilepas menggunakan qd sebelum penutupan debugger, WER akan melaporkan kegagalan tersebut.
Jika sesi debug berhenti dengan 'q' (atau jika debugger ditutup tanpa memutus sambungan), WER tidak akan melaporkan kegagalan.
Tambahkan ; q atau ; qd ke akhir string perintah untuk memanggil perilaku yang diinginkan.
Misalnya, untuk memungkinkan WER melaporkan kegagalan setelah CDB menangkap sebuah dump, konfigurasikan perintah string ini.
<Path>\cdb.exe -p %ld -e %ld -c ".dump /j 0x%p /u c:\Dumps\AeDebug.dmp; qd"
Contoh ini akan memungkinkan WER melaporkan kegagalan setelah WinDbg mengambil dump.
<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd""
Jika Anda mempertimbangkan untuk mengaktifkan debugging postmortem di komputer yang Anda bagikan dengan orang lain, lihat Keamanan Selama Debugging Postmortem.