Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Penginstalan dan penyiapan debugger
Beberapa tindakan Pemverifikasi Aplikasi dapat mengakibatkan pengecualian dinaikkan. Debugger harus diatur untuk menangkap pengecualian ini pada kesempatan kedua, karena Pemverifikasi Aplikasi itu sendiri akan menangani pengecualian kesempatan pertama.
Pengecualian yang dimunculkan adalah dari tiga jenis:
Pengecualian pelanggaran akses (0xC0000005) dihasilkan jika opsi tumpukan mendeteksi buffer tumpukan diserbu. Dalam beberapa kasus, opsi Periksa penggunaan jalur sistem juga dapat menyebabkan pelanggaran akses.
Pengecualian handel yang tidak valid (0xC0000008) dihasilkan ketika opsi Deteksi penggunaan handel yang tidak valid mendeteksi operasi handel yang tidak valid.
Pengecualian luapan tumpukan (0xC00000FD) dihasilkan saat opsi Periksa tumpukan yang memadai mendeteksi bahwa tumpukan awal terlalu pendek.
Salah satu cara untuk mempersiapkan peristiwa ini adalah dengan memulai debugger pada baris perintah sebagai berikut:
windbg -xd av -xd ch -xd sov ApplicationCommandLine
atau
cdb -xd av -xd ch -xd sov ApplicationCommandLine
Jika Anda telah memulai debugger, Anda dapat menggunakan perintah sxd (Atur Pengecualian) untuk menangkap semua pelanggaran akses, handel yang tidak valid, dan tumpukan luapan sebagai pengecualian kesempatan kedua:
0:000> sxd av
0:000> sxd ch
0:000> sxd sov 1
Secara teoritis dimungkinkan untuk mengontrol Pemverifikasi Aplikasi melalui debugger kernel. Namun, ini tidak disarankan — memerlukan penggunaan perintah .process dan .pagein yang sering, namun tidak memberi Anda kekuatan lebih daripada menggunakan debugger mode pengguna.
Menginstal alat penelusuran kesalahan
Untuk mengunduh alat versi terbaru, lihat Mengunduh Alat Debugging untuk Windows.
Mengonfigurasi Perangkat Keras untuk Penelusuran Kesalahan User-Mode
Penelusuran kesalahan mode pengguna umumnya dilakukan pada satu komputer: debugger dijalankan pada komputer yang sama dengan aplikasi yang gagal.
Dalam hal ini, tidak diperlukan penyiapan perangkat keras tertentu. Sepanjang topik ini, istilah komputer host dan komputer target dapat dipertukarkan dalam hal ini.
Mengonfigurasi Perangkat Lunak untuk Penelusuran Kesalahan User-Mode
Konfigurasi User-Mode Dasar - Sebelum dapat memulai penelusuran kesalahan mode pengguna, Anda harus mengunduh file simbol yang diperlukan dan mengatur variabel lingkungan tertentu.
File Simbol
Anda harus mengunduh file simbol untuk proses mode pengguna yang sedang di-debug. Jika ini adalah aplikasi yang telah Anda tulis, aplikasi harus dibangun dengan file simbol lengkap. Jika ini adalah aplikasi komersial, file simbol mungkin tersedia di server web atau untuk diunduh, hubungi produsen.
jika Anda melakukan penelusuran kesalahan jarak jauh, lokasi file simbol bergantung pada metode yang Anda gunakan:
Jika Anda melakukan penelusuran kesalahan jarak jauh melalui debugger, file simbol harus berada di komputer dengan server penelusuran kesalahan.
Jika Anda melakukan penelusuran kesalahan jarak jauh melalui remote.exe, file simbol harus berada di komputer dengan debugger.
Jika Anda melakukan penelusuran kesalahan jarak jauh melalui server proses atau server koneksi KD, file simbol harus berada di komputer dengan klien pintar.
Jika Anda mengontrol debugger mode pengguna dari debugger kernel, file simbol harus berada di kedua komputer.
Mengonfigurasi Variabel Lingkungan
Debugger menggunakan berbagai variabel lingkungan untuk menunjukkan sejumlah pengaturan penting.
Untuk informasi selengkapnya tentang debugger, lihat Memulai Penelusuran Kesalahan Windows
Mengonfigurasi Pemverifikasi Aplikasi dengan Debugger menggunakan baris Perintah
Untuk mengonfigurasi Pemverifikasi Aplikasi, Anda dapat menggunakan baris perintah CDB atau NTSD.
Gunakan baris perintah berikut:
cdb OtherOptions -vf:Flags Target
Di mana Target adalah nama aplikasi target, dan Bendera menentukan opsi Pemverifikasi Aplikasi yang diinginkan yang akan diterapkan ke target ini.
Bendera harus berupa jumlah bit yang mewakili opsi yang diinginkan. Nilai bit individual adalah sebagai berikut:
Nilai bendera | Makna |
---|---|
00000001 | PEMERIKSAAN TIMBUNAN |
00000004 | MENANGANI PEMERIKSAAN |
00000008 | PEMERIKSAAN SIM SUMBER DAYA RENDAH |
00000020 | PEMERIKSAAN TLS |
00000040 | TUMPUKAN KOTOR |
00000200 | API BERBAHAYA |
00001000 | PEMERIKSAAN PENGECUALIAN |
00002000 | PEMERIKSAAN MEMORI |
00020000 | PEMERIKSAAN LAIN-LAIN |
00040000 | PEMERIKSAAN KUNCI |
Penelusuran kesalahan dengan !avrf
Ekstensi !avrf mengontrol pengaturan Pemverifikasi Aplikasi dan menampilkan berbagai output yang dihasilkan oleh Pemverifikasi Aplikasi. Untuk informasi tambahan tentang ekstensi !arvrf, lihat !avrf di dokumen debugger.
Sintaks
!avrf
Perintah !avrf tanpa parameter menunjukkan pengaturan Pemverifikasi Aplikasi dan informasi tentang Pemverifikasi Aplikasi saat ini dan sebelumnya rusak jika ada.
!avrf –vs { Length | -aAddress }
Menampilkan log operasi ruang virtual. Panjang menentukan jumlah rekaman yang akan ditampilkan mulai dari yang terbaru. Alamat menentukan alamat virtual. Rekaman operasi virtual yang berisi alamat virtual ini akan ditampilkan.
!avrf -hp { Length | -a Address }
Menampilkan log operasi timbunan. Alamat menentukan alamat timbunan. Rekaman operasi timbunan yang berisi alamat timbunan ini akan ditampilkan.
!avrf -cs { Length | -a Address }
Menampilkan log penghapusan bagian penting. Panjang menentukan jumlah rekaman yang akan ditampilkan mulai dari yang terbaru. Alamat menentukan alamat bagian penting. Rekaman untuk bagian penting tertentu ditampilkan saat Alamat ditentukan.
!avrf -dlls [ Length ]
Menampilkan log muat/bongkar DLL. Panjang menentukan jumlah rekaman yang akan ditampilkan mulai dari yang terbaru.
!avrf -trm
Menampilkan log dari semua utas yang dihentikan dan ditangguhkan.
!avrf -ex [ Length ]
Menampilkan log pengecualian. Pemverifikasi Aplikasi melacak semua pengecualian yang terjadi dalam aplikasi.
!avrf -threads [ ThreadID ]
Menampilkan informasi tentang utas dalam proses target. Untuk utas anak, ukuran tumpukan dan bendera CreateThread yang ditentukan oleh induk juga ditampilkan. Memberikan ID utas hanya akan menampilkan informasi untuk utas tertentu.
!avrf -tp [ ThreadID ]
Menampilkan log kumpulan utas. Log ini mungkin berisi jejak tumpukan untuk berbagai operasi seperti mengubah masker afinitas utas, mengubah prioritas utas, memposting pesan utas, menginisialisasi COM, dan membatalkan inisialisasi COM dari dalam panggilan balik kumpulan utas. Memberikan ID utas hanya akan menampilkan informasi untuk utas tertentu.
!avrf -srw [ Address | Address Length ] [ -stats ]
Menampilkan log Slim Reader/Writer (SRW). Menentukan Alamat akan menampilkan rekaman yang berkaitan dengan alamat kunci SRW tersebut. Ketika Panjang ditentukan bersama dengan Alamat , semua kunci SRW dalam rentang alamat tersebut ditampilkan. Opsi -stats membuang statistik kunci SRW.
!avrf -leak [ -m ModuleName ] [ -r ResourceType ] [ -a Address ] [ -t ]
Menampilkan log sumber daya yang luar biasa. Sumber daya ini mungkin atau mungkin tidak bocor pada titik tertentu. Menentukan ModuleName (termasuk ekstensi) menampilkan semua sumber daya yang luar biasa dalam modul yang ditentukan. Menentukan ResourceType menampilkan sumber daya luar biasa dari jenis sumber daya tertentu. Menentukan Alamat mencadangkan rekaman sumber daya yang luar biasa dengan alamat tersebut. ResourceType bisa menjadi salah satu hal berikut ini:
- Heap: Menampilkan alokasi heap menggunakan API Heap Win32
- Lokal: Menampilkan alokasi Lokal/Global
- CRT: Menampilkan alokasi menggunakan API CRT
- Virtual: Menampilkan Reservasi virtual
- BSTR: Menampilkan alokasi BSTR
- Registri: Menampilkan kunci Registri terbuka
- Daya: Menampilkan objek pemberitahuan daya
- Handel: Menampilkan alokasi utas, file, dan penanganan peristiwa
!avrf –trace TraceIndex
Menampilkan jejak tumpukan untuk indeks pelacakan yang ditentukan. Beberapa struktur menggunakan nomor indeks 16-bit ini untuk mengidentifikasi jejak tumpukan. Indeks ini menunjuk ke lokasi dalam database pelacakan tumpukan. Jika Anda menganalisis struktur seperti itu, Anda akan menemukan sintaks ini berguna.
!avrf -cnt
Menampilkan daftar penghitung global.
!avrf -brk [ BreakEventType ]
Menentukan bahwa ini adalah perintah break-event. Ketika !avrf -brk
digunakan tanpa parameter tambahan, pengaturan peristiwa pemutusan ditampilkan. BreakEventType menentukan nomor jenis peristiwa pemutusan. Untuk daftar jenis yang mungkin, gunakan !avrf -brk
.
!avrf -flt [ EventTypeProbability ]
Menentukan bahwa ini adalah perintah injeksi kesalahan. Ketika !avrf -flt
digunakan tanpa parameter tambahan, pengaturan injeksi kesalahan saat ini ditampilkan. EventType menentukan nomor jenis peristiwa. Probabilitas menentukan frekuensi di mana peristiwa akan gagal. Ini bisa berupa bilangan bulat antara 0 dan 1.000.000 (0xF4240).
!avrf -flt break EventType
Menyebabkan Pemverifikasi Aplikasi masuk ke debugger setiap kali kesalahan ini disuntikkan.
!avrf -flt stacks Length
Menampilkan Panjang jumlah pelacakan tumpukan untuk operasi yang disuntikkan kesalahan terbaru.
!avrf -trg [ StartEnd | dll Module | all ]
Menentukan bahwa ini adalah perintah rentang target. Ketika -trg digunakan tanpa parameter tambahan, rentang target saat ini ditampilkan. Mulai menentukan alamat awal rentang target atau rentang pengecualian. Akhir menentukan alamat akhir rentang target atau rentang pengecualian. Modul menentukan nama modul yang akan ditargetkan atau dikecualikan. Modul harus menyertakan nama modul lengkap, termasuk ekstensi .exe atau .dll. Informasi jalur tidak boleh disertakan. Menentukan semua penyebab semua rentang target atau rentang pengecualian direset.
!avrf -skp [ StartEnd | dll Module | all | Time ]
Menentukan bahwa ini adalah perintah rentang pengecualian. Mulai menentukan alamat awal rentang target atau rentang pengecualian. Akhir menentukan alamat akhir rentang target atau rentang pengecualian. Modul menentukan nama modul yang akan ditargetkan atau dikecualikan. Modul harus menyertakan nama modul lengkap, termasuk ekstensi .exe atau .dll. Informasi jalur tidak boleh disertakan. Menentukan semua penyebab semua rentang target atau rentang pengecualian direset. Menentukan Waktu menyebabkan semua kesalahan ditekan untuk Waktu milidetik setelah eksekusi dilanjutkan.
Berikut ini adalah output yang disediakan oleh perintah !avrf dalam debugger.
0:000> !avrf
Application verifier settings (816431A7):
- full page heap
- COM
- RPC
- Handles
- Locks
- Memory
- TLS
- Exceptions
- Threadpool
- Leak
- SRWLock
No verifier stop active.
Note: Sometimes bugs found by verifier manifest themselves as raised
exceptions (access violations, stack overflows, invalid handles),
and it is not always necessary to have a verifier stop.
!avrf extension comments
Ketika ekstensi !avrf digunakan tanpa parameter, ekstensi ini menampilkan opsi Pemverifikasi Aplikasi saat ini.
Ekstensi !avrf menggunakan Exts.dll di debugger.
Jika Pemberhentian Pemverifikasi Aplikasi telah terjadi, ekstensi !avrf tanpa parameter akan mengungkapkan sifat pemberhentian dan apa yang menyebabkannya.
Jika simbol untuk ntdll.dll dan verifier.dll hilang, ekstensi !avrf akan menghasilkan pesan kesalahan.
Perhentian yang Dapat Dilanjutkan dan Tidak Dapat Dilanjutkan
Men-debug Penghentian yang Dapat Dilanjutkan
Berikut adalah contoh pengecualian handel yang tidak valid yang telah dinaikkan oleh opsi Deteksi penggunaan handel yang tidak valid.
Pertama, pesan berikut muncul:
Invalid handle - code c0000008 (first chance)
===================================================
VERIFIER STOP 00000300: pid 0x558: invalid handle exception for current stack trace
C0000008 : Exception code.
0012FBF8 : Exception record. Use .exr to display it.
0012FC0C : Context record. Use .cxr to display it.
00000000 :
===================================================
This verifier stop is continuable.
After debugging it use 'go' to continue.
===================================================
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=6a27c280 ecx=6a226447 edx=0012fa4c esi=00942528 edi=6a27c260
eip=6a22629c esp=0012facc ebp=0012faf0 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
6a22629c cc int 3
Perhatikan bahwa pesan memberi tahu Anda bahwa Penghentian Pemverifikasi Aplikasi ini dapat dilanjutkan. Setelah Anda memahami apa yang telah terjadi, Anda dapat terus menjalankan aplikasi target.
Pertama, Anda harus menggunakan ekstensi !avrf. Ini memberikan informasi tentang kegagalan saat ini:
0:000> !avrf
Global flags: 00000100
Application verifier global flag is set.
Application verifier settings (00000004):
- no heap checking enabled!
- handle checks
Page heap is not active for this process.
Current stop 00000300 : c0000008 0012fbf8 0012fc0c 00000000 .
Using an invalid handle (either closed or simply bad).
Baris akhir tampilan ini meringkas masalah.
Anda mungkin ingin melihat beberapa log pada saat ini. Setelah selesai, gunakan perintah g (Go) untuk memulai aplikasi lagi:
0:000> g
## Debugging a Non-Continuable Stop
Here is an example of an access violation that has been raised by the page heap option.
First, the following message appears:
Access violation - code c0000005 (first chance)
===================================================
VERIFIER STOP 00000008: pid 0x504: exception raised while verifying block header
00EC1000 : Heap handle
00F10FF8 : Heap block
00000000 : Block size
00000000 :
===================================================
This verifier stop is not continuable. Process will be terminated when you use the 'go' debugger command.
===================================================
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=6a226447 edx=0012fab7 esi=00f10ff8 edi=00000008
eip=6a22629c esp=0012fb5c ebp=0012fb80 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
6a22629c cc int 3
Dalam hal ini, pesan memberi tahu Anda bahwa Penghentian Pemverifikasi Aplikasi ini tidak dapat dilanjutkan. Kesalahan terlalu parah agar proses terus berjalan, dan tidak ada cara bagi Pemverifikasi Aplikasi untuk menyelamatkan proses.
Ekstensi !avrf dapat digunakan untuk memberikan informasi tentang kegagalan saat ini:
0:000> !avrf
Global flags: 02000100
Application verifier global flag is set.
Page heap global flag is set.
Application verifier settings (00000001):
- full page heap
Page heaps active in the process (format: pageheap, lightheap, flags):
00941000 , 00a40000 , 3 (pageheap traces )
00b41000 , 00c40000 , 3 (pageheap traces )
00cb1000 , 00db0000 , 3 (pageheap traces )
00ec1000 , 00fc0000 , 3 (pageheap traces )
Current stop 00000008 : 00ec1000 00f10ff8 00000000 00000000 .
Corrupted heap block.
Baris akhir tampilan ini meringkas masalah.
Anda mungkin juga ingin melihat beberapa log pada saat ini. Anda mungkin ingin menggunakan perintah .restart (Restart Target Application) pada saat ini. Atau mungkin Anda mungkin lebih suka mengakhiri sesi Pemverifikasi Aplikasi Anda dan mulai memperbaiki bug dalam kode Anda.
Men-debug Kesalahan Bagian Kritis
!cs ekstensi debugger
!cs dapat digunakan dalam debugger mode pengguna dan debugger kernel untuk menampilkan informasi tentang bagian penting dalam proses saat ini. Untuk informasi tambahan tentang ekstensi !cs, lihat !cs di dokumen debugger.
Simbol yang cocok dengan informasi jenis diperlukan, terutama untuk ntdll.dll.
Sintaks untuk ekstensi ini adalah:
!cs [-s] - buang semua bagian penting aktif dalam proses saat ini.
!cs [-s] address - dump critical section di alamat ini.
!cs [-s] -d address - dump critical section yang sesuai dengan DebugInfo di alamat ini.
-s akan membuang jejak tumpukan inisialisasi bagian kritis jika tersedia.
Contoh:
Mencadangkan informasi tentang bagian penting menggunakan alamatnya
0:001> ! cs 0x7803B0F8
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
DebugInfo = 0x6A262080
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Buang informasi tentang bagian penting menggunakan alamatnya, termasuk pelacakan tumpukan inisialisasi
0:001> !cs -s 0x7803B0F8
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
DebugInfo = 0x6A262080
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A262080:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
Membuang informasi tentang bagian penting menggunakan alamat info debugnya
0:001> !cs -d 0x6A262080
DebugInfo = 0x6A262080
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Buang informasi tentang bagian penting menggunakan alamat info debugnya, termasuk jejak tumpukan inisialisasi
0:001> !cs -s -d 0x6A262080
DebugInfo = 0x6A262080
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A262080:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE
Buang informasi tentang semua bagian penting aktif dalam proses saat ini
0:001> !cs
-----------------------------------------
DebugInfo = 0x6A261D60
Critical section = 0x6A262820 (ntdll!RtlCriticalSectionLock+0x0)
LOCKED
LockCount = 0x0
OwningThread = 0x460
RecursionCount = 0x1
LockSemaphore = 0x0
SpinCount = 0x0
-----------------------------------------
DebugInfo = 0x6A261D80
Critical section = 0x6A262580 (ntdll!DeferedCriticalSection+0x0)
NOT LOCKED
LockSemaphore = 0x7FC
SpinCount = 0x0
-----------------------------------------
DebugInfo = 0x6A262600
Critical section = 0x6A26074C (ntdll!LoaderLock+0x0)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
.....
Buang informasi tentang semua bagian penting aktif dalam proses saat ini, termasuk pelacakan tumpukan inisialisasi
0:001> !cs -s
...
-----------------------------------------
DebugInfo = 0x6A261EA0
Critical section = 0xA8001C (+0xA8001C)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
No stack trace saved
-----------------------------------------
DebugInfo = 0x6A261EC0
Critical section = 0x6A263560 (ntdll!RtlpDphTargetDllsLock+0x0)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
No stack trace saved
-----------------------------------------
DebugInfo = 0x6A261EE0
Critical section = 0xA90608 (+0xA90608)
NOT LOCKED
LockSemaphore = 0x7EC
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A261EE0:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A20B0DC: ntdll!CsrpConnectToServer+0x1BE
0x6A20B2AA: ntdll!CsrClientConnectToServer+0x148
0x77DBE83F: KERNEL32!BaseDllInitialize+0x11F
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
-----------------------------------------
DebugInfo = 0x6A261F00
Critical section = 0x77E1AEB8 (KERNEL32!BaseDllRegistryCache+0x18)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A261F00:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
Kesalahan Pengecualian Debugging
Log pengecualian mencatat semua pengecualian yang telah terjadi dalam proses target.
Anda dapat menggunakan perintah ekstensi !avrf -ex Length untuk menampilkan beberapa pengecualian terakhir; Panjang menentukan jumlah pengecualian. Jika Panjang dihilangkan, semua pengecualian ditampilkan.
Ini contohnya:
0:000> !avrf -ex 4
=================================
Thread ID: 0000052c
Exception code: c0000008
Exception address: 6a226663
Exception record: 0012fb50
Context record: 0012fb64
Displayed 1 exception log entries.
Kesalahan Penanganan Debugging
!htrace dapat digunakan dalam debugger mode pengguna dan debugger kernel untuk menampilkan informasi pelacakan tumpukan untuk satu atau semua handel dalam proses. Informasi ini tersedia jika pelacakan penanganan diaktifkan untuk proses - diaktifkan secara otomatis jika pemeriksaan handel diaktifkan di pemverifikasi aplikasi. Jejak tumpukan disimpan setiap kali proses membuka atau menutup handel atau ketika merujuk handel yang tidak valid. Untuk informasi tambahan tentang ekstensi !htrace, lihat !htrace di dokumen debugger.
Sintaks debugger kernel untuk ekstensi ini adalah:
!htrace [ handle [process] ]
Jika handel tidak ditentukan atau 0, informasi tentang semua handel dalam proses akan ditampilkan. Jika proses tidak ditentukan, proses saat ini akan digunakan.
Sintaks debugger mode pengguna adalah:
!htrace [handle]
Ekstensi debugger mode pengguna selalu menampilkan informasi tentang proses debugee saat ini.
Contoh:
Membuang informasi tentang menangani 7CC dalam proses 815328b0
kd> !htrace 7CC 815328b0
Loaded \\...\kdexts extension DLL
Process 0x815328B0
ObjectTable 0xE15ECBB8
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x77DBFCD6: KERNEL32!GetLocaleFileInfo+0x3D
0x77DBF942: KERNEL32!NlsProcessInitialize+0x11D
0x77E0C6DF: KERNEL32!NlsDllInitialize+0x35
0x6A20785C: ntdll!LdrpCallInitRoutine+0x14
0x6A205393: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DD80: ntdll!LdrpInitializeProcess+0xAF6
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3180: ntoskrnl!ObpCreateHandle+0x304
0x801E1563: ntoskrnl!ObOpenObjectByName+0x1E9
0x77DBFCD6: KERNEL32!GetLocaleFileInfo+0x3D
0x77DBF942: KERNEL32!NlsProcessInitialize+0x11D
0x77E0C6DF: KERNEL32!NlsDllInitialize+0x35
0x6A20785C: ntdll!LdrpCallInitRoutine+0x14
0x6A205393: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DD80: ntdll!LdrpInitializeProcess+0xAF6
--------------------------------------
Parsed 0x1CA stack traces.
Dumped 0x2 stack traces.
Buang informasi tentang semua handel dalam proses 815328b0
kd> !htrace 0 81400300
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE23B2: KERNEL32!CreateSemaphoreA+0x66
0x010011C5: badhandle!main+0x45
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x5 stack traces.
Membuang informasi tentang menangani 7DC dalam proses saat ini
kd> !htrace 7DC
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x3 stack traces.
Kesalahan Timbunan Debugging
Ekstensi debugger pemverifikasi timbunan
Ekstensi debugger pemverifikasi timbunan adalah bagian dari ekstensi !heap (ekstensi debugger heap NT). Bantuan sederhana dapat diperoleh dengan !heap -? atau lebih luas dengan !heap -p -? . Ekstensi saat ini tidak mendeteksi sendiri jika tumpukan halaman diaktifkan untuk proses dan bertindak sesuai. Untuk saat ini pengguna ekstensi perlu mengetahui bahwa tumpukan halaman diaktifkan dan menggunakan perintah yang diawali oleh !heap -p . Untuk informasi tambahan tentang ekstensi !htrace, lihat !heap di dokumen debugger.
!heap -p
Alamat cadangan dari semua timbunan halaman penuh yang dibuat dalam proses.
!heap -p -h ADDRESS-OF-HEAP
Pembuangan penuh timbunan halaman penuh di ADDRESS-OF-HEAP.
!heap -p -a ADDRESS
Mencoba mencari tahu apakah ada blok tumpuk di ADDRESS. Nilai ini tidak perlu menjadi alamat awal blok. Perintah ini berguna jika tidak ada petunjuk apa pun tentang sifat area memori.
Log operasi timbunan
Log operasi timbunan melacak semua rutinitas timbunan. Ini termasuk HeapAlloc, HeapReAlloc, dan HeapFree.
Anda dapat menggunakan !avrf -hp Length
perintah ekstensi untuk menampilkan beberapa rekaman terakhir; Panjang menentukan jumlah rekaman.
Anda dapat menggunakan !avrf -hp -a Address
untuk menampilkan semua operasi ruang timbunan yang memengaruhi Alamat yang ditentukan. Untuk operasi alokasi, sudah cukup bahwa Alamat terkandung dalam blok timbunan yang dialokasikan. Untuk operasi gratis, alamat yang tepat dari awal blok harus diberikan.
Untuk setiap entri dalam log, informasi berikut ditampilkan:
- Fungsi timbunan dipanggil.
- ID utas dari utas yang disebut rutinitas.
- Alamat yang terlibat dalam panggilan — ini adalah alamat yang dikembalikan oleh rutinitas alokasi atau yang diteruskan ke rutinitas gratis.
- Ukuran wilayah yang terlibat dalam panggilan.
- Jejak tumpukan panggilan.
Entri terbaru ditampilkan terlebih dahulu.
Dalam contoh ini, dua entri terbaru ditampilkan:
0:001> !avrf -hp 2
alloc (tid: 0xFF4):
address: 00ea2fd0
size: 00001030
00403062: Prymes!_heap_alloc_dbg+0x1A2
00402e69: Prymes!_nh_malloc_dbg+0x19
00402e1e: Prymes!_malloc_dbg+0x1E
00404ff3: Prymes!_stbuf+0xC3
00401c23: Prymes!printf+0x43
00401109: Prymes!main+0xC9
00402039: Prymes!mainCRTStartup+0xE9
77e7a278: kernel32!BaseProcessStart+0x23
alloc (tid: 0xFF4):
address: 00ea07d0
size: 00000830
00403062: Prymes!_heap_alloc_dbg+0x1A2
00402e69: Prymes!_nh_malloc_dbg+0x19
00402e1e: Prymes!_malloc_dbg+0x1E
00403225: Prymes!_calloc_dbg+0x25
00401ad5: Prymes!__initstdio+0x45
00401f38: Prymes!_initterm+0x18
00401da1: Prymes!_cinit+0x21
00402014: Prymes!mainCRTStartup+0xC4
77e7a278: kernel32!BaseProcessStart+0x23
Skenario debug umum
Ada beberapa skenario kegagalan yang mungkin ditemui. Beberapa dari mereka membutuhkan sedikit pekerjaan detektif untuk mendapatkan seluruh gambaran.
Pelanggaran akses di halaman yang tidak dapat diakses
Ini terjadi ketika tumpukan halaman penuh diaktifkan jika aplikasi yang diuji mengakses di luar akhir buffer. Ini juga dapat terjadi jika menyentuh blok yang dibebaskan. Untuk memahami apa sifat alamat tempat pengecualian terjadi, Anda perlu menggunakan:
!heap –p –a ADDRESS-OF-AV
Pesan blokir rusak
Pada beberapa saat selama masa pakai alokasi (alokasi, bebas pengguna, bebas nyata) manajer timbunan halaman memeriksa apakah blok memiliki semua pola isian utuh dan header blok memiliki data yang konsisten. Jika ini tidak terjadi, Anda akan mendapatkan pemberhentian pemverifikasi.
Jika blok adalah blok tumpukan halaman penuh (misalnya, jika Anda tahu pasti tumpukan halaman penuh diaktifkan untuk semua alokasi) maka Anda dapat menggunakan "!heap –p –a ADDRESS" untuk mengetahui apa karakteristik blok tersebut.
Jika blok adalah blok timbunan halaman ringan maka Anda perlu mencari tahu alamat awal untuk header blok. Anda dapat menemukan alamat awal dengan membuang 30-40 byte di bawah alamat yang dilaporkan dan mencari pola awal/akhir ajaib untuk header blok (ABCDAAAA, ABCDBBBB, ABCDAAA9, ABCDBBBA).
Header akan memberikan semua informasi yang Anda butuhkan untuk memahami kegagalan. Terutama, pola ajaib akan mengetahui apakah blok dialokasikan atau bebas jika itu adalah tumpukan halaman ringan atau blok tumpukan halaman penuh. Informasi di sini harus dicocokkan dengan hati-hati dengan panggilan yang menyinggung.
Misalnya jika panggilan ke HeapFree dilakukan dengan alamat blok ditambah empat byte, maka Anda akan mendapatkan pesan yang rusak. Header blok akan terlihat baik-baik saja tetapi Anda harus memperhatikan bahwa byte pertama setelah akhir header (byte pertama setelah nilai ajaib 0xDCBAXXXX) memiliki alamat yang berbeda maka yang ada dalam panggilan.
Penunjuk pengisian khusus
Manajer timbunan halaman mengisi alokasi pengguna dengan nilai yang akan terlihat sebagai penunjuk kernel. Ini terjadi ketika blok dibebaskan (nilai isi adalah F0) dan ketika blok dialokasikan tetapi tidak ada permintaan yang dibuat agar blok menjadi nol (nilai isi adalah E0 untuk tumpukan halaman ringan dan C0 untuk tumpukan halaman penuh). Alokasi yang tidak di-nol biasanya untuk pengguna malloc/baru. Jika ada kegagalan (pelanggaran akses) di mana baca/tulis dicoba di alamat seperti F0F0F0F0, E0E0E0E0, C0C0C0C0 maka kemungkinan besar Anda mencapai salah satu kasus ini.
Baca/tulis di F0F0F0F0 berarti blok telah digunakan setelah dibebaskan. Sayangnya Anda akan membutuhkan beberapa pekerjaan detektif untuk mengetahui blok mana yang menyebabkan ini. Anda perlu mendapatkan jejak tumpukan kegagalan dan kemudian memeriksa kode untuk fungsi pada tumpukan. Salah satu dari mereka mungkin membuat asumsi yang salah tentang alokasi yang hidup.
Baca/tulis pada E0E0E0E0/C0C0C0C0 berarti aplikasi tidak menginisialisasi alokasi dengan benar. Ini juga memerlukan inspeksi kode fungsi dalam jejak tumpukan saat ini. Berikut ini adalah contoh untuk kegagalan semacam ini. Dalam proses pengujian, pelanggaran akses saat melakukan HeapFree pada alamat E0E0E0E0 diperhatikan. Ternyata tes mengalokasikan struktur, tidak menginisialisasinya dengan benar dan kemudian disebut destruktor objek. Karena bidang tertentu tidak null (bidang tersebut E0E0E0E0 di dalamnya) bidang tersebut disebut hapus di dalamnya.
Detail Teknis Timbunan Halaman
Untuk mendeteksi kerusakan tumpukan (luapan atau underflow), AppVerifier akan memodifikasi cara memori dialokasikan dengan mengayuh memori yang diminta dengan halaman penuh yang tidak dapat ditulis atau dengan tag khusus sebelum dan sesudah memori yang dialokasikan. AppVerifier melakukan ini dengan memuat Verifier.dll ke dalam proses yang sedang diverifikasi dan mengalihkan beberapa API Heap Win32 yang dipanggil oleh aplikasi ke API Verifier.dll yang sesuai.
Saat mengayuh memori yang diminta dengan halaman penuh yang tidak dapat ditulis (pengaturan PENUH diaktifkan di bagian properti tumpukan halaman dan merupakan pengaturan default), AppVerifier akan mengonsumsi sejumlah besar memori virtual tetapi memiliki keuntungan bahwa peristiwa kerusakan tumpukan di-cache secara real time ketika luapan atau aliran bawah terjadi. Ingatlah bahwa memori dalam mode ini akan terlihat seperti ini [AppVerifier Read-Only Heap Page (4k)] [Jumlah memori yang diminta oleh Aplikasi di bawah pengujian] atau seperti ini [Jumlah memori yang diminta oleh Aplikasi di bawah pengujian] [AppVerifier Read-Only Heap Page (4k)].
Pemeriksaan timbunan akan menempatkan halaman penjaga di awal atau akhir alokasi tergantung pada properti Mundur. Jika Backward diatur ke False, yang merupakan default, itu akan menempatkan halaman penjaga di akhir alokasi untuk menangkap overrun buffer. Jika diatur ke True, halaman penjaga ditempatkan di awal alokasi untuk menangkap underrun buffer.
Saat mengayuh memori yang diminta dengan tag khusus (diaktifkan dengan mengosongkan item kotak centang "Penuh" di properti heap), AppVerifier akan memeriksa dan memperingatkan Anda ketika memori ini dirilis. Masalah utama dalam menggunakan teknik ini adalah bahwa ada beberapa kasus ketika kerusakan memori hanya akan terdeteksi ketika memori dirilis (jumlah minimum blok memori adalah 8 byte), jadi ketika pada variabel 3-byte atau luapan 5-byte terjadi itu tidak akan segera terdeteksi.
Pada peristiwa underflow, upaya akan dilakukan untuk menulis ke halaman Read-Only. Ini akan memicu pengecualian. Perhatikan bahwa pengecualian ini hanya dapat ditangkap jika aplikasi target sedang dijalankan di bawah debugger. Perhatikan bahwa mode tumpukan halaman penuh juga akan mendeteksi kesalahan ini karena menggunakan halaman padding+guard. Alasan Anda akan menggunakan tumpukan halaman ringan adalah jika komputer Anda tidak dapat mentolerir batasan memori tinggi dari tumpukan halaman penuh.
Untuk aplikasi intensif memori, atau ketika diperlukan untuk menggunakan AppVerifier selama jangka waktu yang lama (misalnya, pengujian stres), lebih baik menjalankan pengujian timbunan normal (ringan) alih-alih mode penuh karena penurunan performa. Namun, ketika Anda mengalami masalah, aktifkan tumpukan halaman penuh untuk menyelidiki lebih lanjut.
Aplikasi yang menggunakan tumpukan kustom (tumpukan yang melewati implementasi timbunan sistem operasi) mungkin tidak mendapatkan manfaat penuh menggunakan tumpukan halaman atau bahkan mungkin tidak berfungsi saat diaktifkan.
Kesalahan Memori Penelusuran Kesalahan
Ekstensi debugger pemverifikasi memori
Log operasi ruang virtual melacak semua rutinitas yang memodifikasi ruang virtual proses dengan cara apa pun. Ini termasuk VirtualAlloc, VirtualFree, MapViewOfFile, dan UnmapViewOfFile.
Anda dapat menggunakan !avrf -vs Length
perintah ekstensi untuk menampilkan beberapa rekaman terakhir; Panjang menentukan jumlah rekaman.
Anda dapat menggunakan !avrf -vs -a Address untuk menampilkan semua operasi ruang virtual yang memengaruhi Alamat yang ditentukan. Untuk alokasi, sudah cukup bahwa Alamat terkandung dalam blok yang dialokasikan. Secara gratis, alamat yang tepat dari awal wilayah harus diberikan.
Untuk setiap entri dalam log, informasi berikut ditampilkan:
- Fungsi yang disebut
- ID utas utas yang disebut rutinitas
- Alamat yang terlibat dalam panggilan — ini adalah alamat yang dikembalikan oleh rutinitas alokasi atau yang diteruskan ke rutinitas gratis
- Ukuran wilayah yang terlibat dalam panggilan
- Jenis operasi memori (parameter AllocationType)
- Jenis perlindungan yang diminta
- Jejak tumpukan panggilan
Contoh
Entri terbaru ditampilkan terlebih dahulu.
Dalam contoh berikut, dua entri terbaru ditampilkan:
0:001> !avrf -vs 2
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00400000 op:8000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef6525: mshtml+0x116525
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00001000 op:4000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef65ae: mshtml+0x1165AE
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
Ini dapat dilihat dari output yang utas 0xB4 pertama kali menonaktifkan halaman dan kemudian merilis seluruh wilayah virtual.
Berikut adalah tampilan semua operasi yang memengaruhi alamat 0x4BB1000:
0:001> !avrf -vs -a 4bb1000
Searching in vspace log for address 04bb1000 ...
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00400000 op:8000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef6525: mshtml+0x116525
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualFree (tid: 0xB4): addr:04bb1000 sz:00001000 op:4000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef65ae: mshtml+0x1165AE
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualAlloc (tid: 0xB4): addr:04bb0000 sz:00010000 op:1000 prot:4
00aa1ac2: verifier!VsLogCall+0x42
00aa1988: verifier!AVrfpNtAllocateVirtualMemory+0x37
68925ca3: kernel32!VirtualAllocEx+0x61
68926105: kernel32!VirtualAlloc+0x16
75ef63f3: mshtml+0x1163F3
VirtualAlloc (tid: 0xB4): addr:04bb0000 sz:00400000 op:2000 prot:4
00aa1ac2: verifier!VsLogCall+0x42
00aa1988: verifier!AVrfpNtAllocateVirtualMemory+0x37
68925ca3: kernel32!VirtualAllocEx+0x61
68926105: kernel32!VirtualAlloc+0x16
75ef63d9: mshtml+0x1163D9
Untuk membaca output ini, ingatlah bahwa entri dicadangkan dimulai dengan yang terbaru. Dengan demikian, log ini menunjukkan bahwa utas 0xB4 mengalokasikan wilayah besar di mana ia menerapkan halaman. Kemudian, halaman dinonaktifkan, lalu merilis seluruh wilayah virtual.
Lihat juga
Pemverifikasi Aplikasi - Gambaran Umum
Pemverifikasi Aplikasi - Aplikasi Pengujian
Pemverifikasi Aplikasi - Pengujian dalam Pemverifikasi Aplikasi