Paksa Permintaan I/O Tertunda
Opsi Paksa Permintaan I/O Tertunda secara acak mengembalikan STATUS_PENDING sebagai respons terhadap panggilan driver ke IoCallDriver. Opsi ini menguji logika driver untuk merespons STATUS_PENDING mengembalikan nilai dari IoCallDriver.
Opsi ini hanya didukung pada Windows Vista dan versi sistem operasi Windows yang lebih baru.
Hati Jangan gunakan opsi ini pada driver kecuali Anda memiliki pengetahuan terperinci tentang pengoperasian driver dan telah memverifikasi bahwa driver dirancang untuk menangani STATUS_PENDING mengembalikan nilai dari semua panggilannya ke IoCallDriver. Menjalankan opsi ini pada driver yang tidak dirancang untuk menangani STATUS_PENDING dari semua panggilan dapat mengakibatkan crash, kerusakan memori, dan perilaku sistem yang tidak biasa yang dapat sulit di-debug atau diperbaiki.
Mengapa Menggunakan Permintaan I/O Tertunda Paksa?
Driver tingkat lebih tinggi dalam tumpukan driver memanggil IoCallDriver untuk meneruskan IRP ke driver tingkat bawah di tumpukan driver. Rutinitas pengiriman driver di driver tingkat bawah yang menerima IRP dapat segera menyelesaikan IRP atau mengembalikan STATUS_PENDING dan menyelesaikan IRP di lain waktu.
Biasanya, penelepon harus siap untuk menangani salah satu hasil. Namun, karena sebagian besar rutinitas pengiriman segera menangani IRP, logika STATUS_PENDING di pemanggil tidak sering dilakukan dan kesalahan logika serius mungkin tidak terdeteksi. Opsi Paksa Permintaan I/O Tertunda mencegat panggilan ke IoCallDriver dan mengembalikan STATUS_PENDING untuk menguji logika driver panggilan yang jarang digunakan.
Kapan Anda menggunakan Permintaan I/O Paksa Tertunda?
Sebelum menjalankan pengujian ini, tinjau desain driver dan kode sumber dan konfirmasikan bahwa driver dimaksudkan untuk menangani STATUS_PENDING dari semua panggilan IoCallDriver-nya .
Banyak driver tidak dirancang untuk menangani STATUS_PENDING pada semua panggilan ke IoCallDriver. Mereka mungkin mengirim IRP ke driver terkenal tertentu yang dijamin akan segera menyelesaikan IRP. Mengirim STATUS_PENDING ke driver yang tidak menanganinya dapat menyebabkan crash driver dan sistem dan kerusakan memori.
Bagaimana driver harus menangani STATUS_PENDING?
Driver tingkat lebih tinggi yang memanggil IoCallDriver harus menangani nilai pengembalian STATUS_PENDING sebagai berikut:
Sebelum memanggil IoCallDriver, driver harus memanggil IoBuildSynchronousFsdRequest untuk mengatur pemrosesan IRP yang sinkron.
Jika IoCallDriver mengembalikan STATUS_PENDING, driver harus menunggu penyelesaian IRP dengan memanggil KeWaitForSingleObject pada peristiwa yang ditentukan.
Driver harus mengantisipasi bahwa IRP mungkin dibebaskan sebelum Manajer I/O memberi sinyal peristiwa.
Setelah memanggil IoCallDriver, pemanggil tidak dapat mereferensikan IRP.
Kesalahan Mana yang Dideteksi Paksa Permintaan I/O Tertunda?
Opsi Paksa Permintaan I/O Tertunda mendeteksi kesalahan berikut dalam driver yang memanggil IoCallDriver dan menerima nilai pengembalian STATUS_PENDING:
Driver tidak memanggil IoBuildSynchronousFsdRequest untuk mengatur pemrosesan sinkron.
Driver tidak memanggil KeWaitForSingleObject.
Driver mereferensikan nilai dalam struktur IRP setelah memanggil IoCallDriver. Setelah memanggil IoCallDriver, driver tingkat yang lebih tinggi tidak dapat mengakses IRP kecuali telah mengatur rutinitas penyelesaian dan kemudian, hanya ketika semua driver tingkat bawah telah menyelesaikan IRP. Jika IRP dibebaskan, driver akan mengalami crash.
Driver salah memanggil fungsi terkait. Misalnya, driver memanggil KeWaitForSingleObject dan meneruskan handel ke peristiwa (sebagai parameter Objek ), alih-alih meneruskan pointer ke objek peristiwa.
Driver menunggu peristiwa yang salah. Misalnya, driver memanggil IoSetCompletionRoutine, tetapi menunggu peristiwa internal yang disinyalir oleh rutinitas penyelesaiannya sendiri, alih-alih menunggu peristiwa IRP yang disinyalkan oleh I/O Manager ketika IRP selesai.
Paksa Perubahan Permintaan I/O Tertunda yang Diperkenalkan di Windows 7
Mulai Windows 7, opsi Paksa Permintaan I/O Tertunda lebih efektif dalam memaksa penerapan jalur kode STATUS_PENDING di driver terverifikasi. Di versi Windows sebelumnya, Pemverifikasi Driver memaksa penyelesaian IRP tertunda hanya ketika IoCompleteRequest pertama untuk IRP tersebut dijalankan. Ini berarti bahwa efektivitas verifikasi Driver1 dapat dikurangi oleh perilaku Driver2 dari tumpukan perangkat yang sama. Driver2 mungkin menunggu secara sinkron untuk penyelesaian sebelum kembali dari rutinitas pengirimannya ke Driver1. Penundaan paksa penyelesaian IRP terjadi tepat sebelum permintaan I/O melepas lelah kembali ke driver terverifikasi pada jalur penyelesaian. Ini berarti bahwa jalur kode STATUS_PENDING driver terverifikasi benar-benar dijalankan dan driver terverifikasi menyadari penundaan dalam penyelesaian.
Mengaktifkan Opsi Ini
Untuk mengaktifkan Permintaan I/O Paksa Tertunda, Anda juga harus mengaktifkan Verifikasi I/O. Anda dapat mengaktifkan opsi Paksa Permintaan I/O Tertunda untuk satu atau beberapa driver dengan menggunakan Driver Verifier Manager atau baris perintah Verifier.exe. Untuk detailnya, lihat Memilih Opsi Pemverifikasi Driver.
Opsi Paksa Permintaan I/O Tertunda hanya didukung pada Windows Vista dan versi Windows yang lebih baru.
Pada baris perintah
Untuk mengaktifkan Paksa Permintaan I/O Tertunda, gunakan nilai bendera 0x210 atau tambahkan 0x210 ke nilai bendera. Nilai ini mengaktifkan Verifikasi I/O (0x10), dan Permintaan I/O Paksa Tertunda (0x200).
Contohnya:
verifier /flags 0x210 /driver MyDriver.sys
Opsi akan aktif setelah boot berikutnya.
Jika Anda hanya mencoba mengaktifkan Permintaan I/O Paksa Tertunda (pemverifikasi /bendera 0x200), Pemverifikasi Driver secara otomatis mengaktifkan Permintaan I/O Tertunda Paksa (0x200) dan Verifikasi I/O.
Anda juga dapat mengaktifkan dan menonaktifkan Paksa Permintaan I/O Tertunda tanpa me-reboot komputer dengan menambahkan parameter /volatile ke perintah . Contohnya:
verifier /volatile /flags 0x210 /adddriver MyDriver.sys
Pengaturan ini langsung efektif, tetapi hilang ketika Anda mematikan atau me-reboot komputer. Untuk detailnya, lihat Menggunakan Pengaturan Volatil.
Menggunakan Driver Verifier Manager
- Mulai Manajer Pemverifikasi Driver. Ketik Pemverifikasi di jendela Wantian Perintah.
- Pilih Buat pengaturan kustom (untuk pengembang kode), lalu klik Berikutnya.
- Pilih Pilih pengaturan individual dari daftar lengkap.
- Pilih Verifikasi I/O dan Paksa Permintaan I/O yang Tertunda.
Jika Anda hanya memilih Paksa Permintaan I/O Tertunda, Driver Verifier Manager mengingatkan Anda bahwa Verifikasi I/O diperlukan dan menawarkan untuk mengaktifkannya untuk Anda.
Menampilkan Hasil
Untuk melihat hasil pengujian Force Pending I/O Requests, gunakan ekstensi debugger !verifier dengan nilai bendera 0x40.
Untuk informasi tentang !verifier, lihat topik !verifier di dokumentasi Alat Penelusuran Kesalahan untuk Windows .
Jika mesin uji crash sebagai akibat dari uji Permintaan I/O Paksa Tertunda, Anda dapat menggunakan perintah !verifier 40 untuk menemukan penyebabnya. Dalam pelacakan tumpukan saat ini, temukan alamat IRP yang baru-baru ini digunakan oleh driver Anda. Misalnya, jika Anda menggunakan perintah kP , yang menampilkan bingkai tumpukan untuk utas, Anda dapat menemukan alamat IRP di antara parameter fungsi pelacakan tumpukan saat ini. Kemudian, jalankan !verifier 40 dan cari alamat IRP. Jejak tumpukan tertunda paksa terbaru muncul di bagian atas tampilan.
Misalnya, jejak tumpukan Pci.sys berikut menunjukkan responsnya terhadap Permintaan I/O Paksa Tertunda. Pengujian tidak mengungkapkan kesalahan apa pun dalam logika Pci.sys.
kd> !verifier 40
# Size of the log is 0x40
========================================================
IRP: 8f84ef00 - forced pending from stack trace:
817b21e4 nt!IovpLocalCompletionRoutine+0xb2
81422478 nt!IopfCompleteRequest+0x15c
817b2838 nt!IovCompleteRequest+0x9c
84d747df acpi!ACPIBusIrpDeviceUsageNotification+0xf5
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84fed489 pci!PciCallDownIrpStack+0xbf
84fde1cb pci!PciDispatchPnpPower+0xdf
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84ff2ff5 pci!PciSendPnpIrp+0xbd
84fec820 pci!PciDevice_DeviceUsageNotification+0x6e
84fde1f8 pci!PciDispatchPnpPower+0x10c
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84d76ce2 acpi!ACPIFilterIrpDeviceUsageNotification+0x96
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84f7f16c PCIIDEX!PortWdmForwardIrpSynchronous+0x8e
84f7b2b3 PCIIDEX!GenPnpFdoUsageNotification+0xcb
84f7d301 PCIIDEX!PciIdeDispatchPnp+0x45
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
Jejak tumpukan menunjukkan bahwa Acpi.sys mencoba menyelesaikan IRP 8f84ef00. Driver Verifier memaksa penyelesaian yang ditangguhkan, jadi Acpi.sys kembali STATUS_PENDING ke pci! PciCallDownIrpStack. Jika panggilan ini telah menyebabkan crash, pemilik driver perlu meninjau kode sumber untuk pci! PciCallDownIrpStack dan revisi untuk menangani STATUS_PENDING dengan benar.