Bagikan melalui


Membaca dan Memfilter Pesan Penelusuran Kesalahan

Rutinitas DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, dan KdPrintEx mengirim pesan ke debugger kernel dalam kondisi yang Anda tentukan. Prosedur ini memungkinkan Anda memfilter pesan berprioritas rendah.

Catatan

Di Microsoft Windows Server 2003 dan versi Windows yang lebih lama, rutinitas DbgPrint dan KdPrint mengirim pesan ke debugger kernel tanpa syarat. Di Windows Vista dan versi Windows yang lebih baru, rutinitas ini mengirim pesan secara kondisional, seperti DbgPrintEx dan KdPrintEx. Versi Windows mana pun yang Anda gunakan, Anda harus menggunakan DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, dan KdPrintEx, karena rutinitas ini memungkinkan Anda mengontrol kondisi di mana pesan dikirim.

Untuk memfilter pesan penelusuran kesalahan

  1. Untuk setiap pesan yang ingin Anda kirim ke debugger, gunakan DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, atau KdPrintEx dalam kode driver Anda. Teruskan nama komponen yang sesuai ke parameter ComponentId , dan teruskan nilai ke parameter Tingkat yang mencerminkan tingkat keparahan atau sifat pesan ini. Pesan itu sendiri diteruskan ke parameter Format dan argumen dengan menggunakan sintaks yang sama dengan printf.

  2. Atur nilai masker filter komponen yang sesuai. Setiap komponen memiliki masker yang berbeda. Nilai masker menunjukkan pesan komponen mana yang ditampilkan. Anda dapat mengatur masker filter komponen di registri dengan menggunakan editor registri atau dalam memori dengan menggunakan debugger kernel.

  3. Lampirkan debugger kernel ke komputer. Setiap kali driver Anda meneruskan pesan ke DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, atau KdPrintEx, nilai yang diteruskan ke ComponentId dan Level dibandingkan dengan nilai masker filter komponen yang sesuai. Jika nilai-nilai ini memenuhi kriteria tertentu, pesan dikirim ke debugger kernel dan ditampilkan. Jika tidak, tidak ada pesan yang dikirim.

Catatan

Semua referensi di halaman ini ke DbgPrintEx berlaku sama untuk KdPrintEx, vDbgPrintEx, dan vDbgPrintExWithPrefix.

Mengidentifikasi Nama Komponen

Setiap komponen memiliki masker filter terpisah. Ini memungkinkan debugger untuk mengonfigurasi filter untuk setiap komponen secara terpisah.

Setiap komponen disebut dengan cara yang berbeda, tergantung pada konteksnya. Dalam parameter ComponentIdDbgPrintEx, nama komponen diawali dengan "DPFLTR_" dan diakhiri dengan "_ID". Dalam registri, masker filter komponen memiliki nama yang sama dengan komponen itu sendiri. Dalam debugger, masker filter komponen diawali dengan "Kd_" dan diakhiri dengan "_Mask".

Ada daftar lengkap semua nama komponen (dalam format DPFLTR_XXXX_ID) dalam header Microsoft Windows Driver Kit (WDK) dpfilter.h. Sebagian besar nama komponen ini disediakan untuk Windows dan untuk driver yang ditulis oleh Microsoft.

Ada enam nama komponen yang disediakan untuk vendor perangkat keras independen. Untuk menghindari pencampuran output driver Anda dengan output komponen Windows, Anda harus menggunakan salah satu nama komponen berikut:

Nama Komponen Jenis driver
IHVVIDEO Driver video
IHVAUDIO Driver audio
IHVNETWORK Driver jaringan
IHVSTREAMING Driver streaming kernel
IHVBUS Sopir bus
IHVDRIVER Jenis driver lainnya

Misalnya, jika Anda menulis driver video, Anda akan menggunakan DPFLTR_IHVVIDEO_ID sebagai parameter ComponentIdDbgPrintEx, menggunakan nama nilai IHVVIDEO di registri, dan merujuk ke Kd_IHVVIDEO_Mask di debugger.

Semua pesan yang dikirim oleh DbgPrint dan KdPrint dikaitkan dengan komponen DEFAULT .

Memilih Tingkat yang Benar

Parameter Level dari rutinitas DbgPrintEx berjenis DWORD. Ini digunakan untuk menentukan bidang bit penting. Koneksi antara parameter Level dan bidang bit ini tergantung pada ukuran Level:

  • Jika Level sama dengan angka antara 0 dan 31, inklusif, itu ditafsirkan sebagai pergeseran bit. Bidang bit kepentingan diatur ke nilai 1 <<Tingkat. Dengan demikian memilih nilai antara 0 dan 31 untuk Level menghasilkan bidang bit dengan tepat satu set bit. Jika Level adalah 0, bidang bit setara dengan 0x00000001; jika Level adalah 31, bidang bit setara dengan 0x80000000.

  • Jika Level adalah angka antara 32 dan 0xFFFFFFFF inklusif, bidang bit kepentingan diatur ke nilai Level itu sendiri.

Dengan demikian, jika Anda ingin mengatur bidang bit ke 0x00004000, Anda dapat menentukan Level sebagai 0x00004000 atau hanya sebagai 14. Perhatikan bahwa nilai bidang bit tertentu tidak dimungkinkan oleh sistem ini -- termasuk bidang bit yang sepenuhnya nol.

Konstanta berikut dapat berguna untuk mengatur nilai Level. Mereka didefinisikan dalam header Microsoft Windows Driver Kit (WDK) dpfilter.h dan header Windows SDK ntrtl.h:

#define   DPFLTR_ERROR_LEVEL     0
#define   DPFLTR_WARNING_LEVEL   1
#define   DPFLTR_TRACE_LEVEL     2
#define   DPFLTR_INFO_LEVEL      3
#define   DPFLTR_MASK   0x80000000

Salah satu cara mudah untuk menggunakan parameter Level adalah dengan selalu menggunakan nilai antara 0 dan 31 -- menggunakan bit 0, 1, 2, 3 dengan arti yang diberikan oleh DPFLTR_XXXX_LEVEL, dan menggunakan bit lain untuk berarti apa pun yang Anda pilih.

Cara mudah lain untuk menggunakan parameter Level adalah dengan selalu menggunakan bidang bit eksplisit. Jika Anda memilih metode ini, Anda mungkin ingin ATAU nilai DPFLTR_MASK dengan bidang bit Anda; ini memastikan bahwa Anda tidak akan secara tidak sengaja menggunakan nilai kurang dari 32.

Untuk membuat driver Anda kompatibel dengan cara Windows menggunakan tingkat pesan, Anda hanya boleh mengatur bit terendah (0x1) dari bidang bit penting jika terjadi kesalahan serius. Jika Anda menggunakan nilai Tingkat kurang dari 32, ini sesuai dengan DPFLTR_ERROR_LEVEL. Jika bit ini diatur, pesan Anda akan dilihat setiap kali seseorang melampirkan debugger kernel ke komputer tempat driver Anda berjalan.

Tingkat peringatan, pelacakan, dan informasi harus digunakan dalam situasi yang sesuai. Bit lain dapat digunakan secara bebas untuk tujuan apa pun yang menurut Anda berguna. Ini memungkinkan Anda untuk memiliki berbagai jenis pesan yang dapat dilihat atau disembunyikan secara selektif.

Semua pesan yang dikirim oleh DbgPrint dan KdPrint berperilaku seperti pesan DbgPrintEx dan KdPrintEx dengan Level sama dengan DPFLTR_INFO_LEVEL. Dengan kata lain, pesan-pesan ini memiliki bit ketiga dari set bidang bit pentingnya.

Mengatur Masker Filter Komponen

Ada dua cara untuk mengatur masker filter komponen:

  • Masker filter komponen dapat diakses di kunci registri HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. Menggunakan editor registri, buat atau buka kunci ini. Di bawah kunci ini, buat nilai dengan nama komponen yang diinginkan, dalam huruf besar. Atur sama dengan nilai DWORD yang ingin Anda gunakan sebagai masker filter komponen.

  • Jika debugger kernel aktif, ia dapat mengakses nilai masker filter komponen dengan mendereferensikan alamat yang disimpan dalam simbol Kd_XXXX_Mask, di mana XXXX adalah nama komponen yang diinginkan. Anda dapat menampilkan nilai masker ini di WinDbg atau KD dengan perintah dd (Display DWORD), atau memasukkan masker filter komponen baru dengan perintah ed (Enter DWORD). Jika ada bahaya ambiguitas simbol, Anda mungkin ingin menentukan simbol ini sebagai nt! Kd_XXXX_Mask.

Filter masker yang disimpan dalam registri berlaku selama boot. Masker filter yang dibuat oleh debugger segera berlaku, dan bertahan hingga Windows di-boot ulang. Nilai yang ditetapkan dalam registri dapat ditimpa oleh debugger, tetapi masker filter komponen akan kembali ke nilai yang ditentukan dalam registri jika sistem di-boot ulang.

Ada juga masker di seluruh sistem yang disebut WIN2000. Ini sama dengan 0x1 secara default, meskipun dapat diubah melalui registri atau debugger seperti semua komponen lainnya. Saat pemfilteran dilakukan, setiap masker filter komponen adalah ORed pertama dengan masker WIN2000 . Secara khusus, ini berarti bahwa komponen yang maskernya belum pernah ditentukan default untuk 0x1.

Kriteria untuk Menampilkan Pesan

Ketika DbgPrintEx dipanggil dalam kode mode kernel, Windows membandingkan bidang bit penting pesan yang ditentukan oleh Tingkat dengan masker filter komponen yang ditentukan oleh ComponentId.

Catatan

Ingat bahwa ketika parameter Level adalah antara 0 dan 31, bitfield kepentingan sama dengan 1 <<Level. Tetapi ketika parameter Level adalah 32 atau lebih tinggi, bitfield kepentingan hanya sama dengan Level.

Windows melakukan operasi AND pada bidang bit penting dan masker filter komponen. Jika hasilnya bukan nol, pesan dikirim ke debugger.

Contoh Filter Debug

Misalkan sebelum boot terakhir, Anda membuat nilai berikut di kunci Filter Cetak Debug :

  • IHVVIDEO, dengan nilai yang sama dengan DWORD 0x2

  • IHVBUS, sama dengan 0x7FF DWORD

Sekarang Anda mengeluarkan perintah berikut di debugger kernel:

kd> ed Kd_IHVVIDEO_Mask 0x8 
kd> ed Kd_IHVAUDIO_Mask 0x7 

Pada titik ini, komponen IHVVIDEO memiliki masker filter 0x8, komponen IHVAUDIO memiliki masker filter 0x7, dan komponen IHVBUS memiliki masker filter 0x7FF.

Namun, karena masker ini secara otomatis ORed dengan masker seluruh sistem WIN2000 (yang biasanya sama dengan 0x1), masker IHVVIDEO secara efektif sama dengan 0x9. Memang, komponen yang masker filternya belum diatur sama sekali (misalnya, IHVSTREAMING atau DEFAULT) akan memiliki masker filter 0x1.

Sekarang misalkan panggilan fungsi berikut terjadi di berbagai driver:

DbgPrintEx( DPFLTR_IHVVIDEO_ID,  DPFLTR_INFO_LEVEL,   "First message.\n");
DbgPrintEx( DPFLTR_IHVAUDIO_ID,  7,                   "Second message.\n");
DbgPrintEx( DPFLTR_IHVBUS_ID,    DPFLTR_MASK | 0x10,  "Third message.\n");
DbgPrint( "Fourth message.\n");

Pesan pertama memiliki parameter Level-nya sama dengan DPFLTR_INFO_LEVEL, yaitu 3. Karena kurang dari 32, ini diperlakukan sebagai pergeseran bit, menghasilkan bidang bit penting 0x8. Nilai ini kemudian DIANDed dengan masker filter komponen IHVVIDEO yang efektif dari 0x9, memberikan hasil yang bukan nol. Jadi pesan pertama dikirimkan ke debugger.

Pesan kedua memiliki parameter Level-nya sama dengan 7. Sekali lagi, ini diperlakukan sebagai pergeseran bit, menghasilkan bidang bit penting 0x80. Ini kemudian DIANDed dengan masker filter komponen IHVAUDIO dari 0x7, memberikan hasil nol. Jadi pesan kedua tidak ditransmisikan.

Pesan ketiga memiliki parameter Level yang sama dengan DPFLTR_MASK | 0x10. Ini lebih besar dari 31, dan oleh karena itu bidang bit kepentingan diatur sama dengan nilai Tingkat -- dengan kata lain, ke 0x80000010. Ini kemudian DIANDed dengan masker filter komponen IHVBUS dari 0x7FF, memberikan hasil bukan nol. Jadi pesan ketiga dikirimkan ke debugger.

Pesan keempat diteruskan ke DbgPrint alih-alih DbgPrintEx. Di Windows Server 2003 dan versi Windows yang lebih lama, pesan yang diteruskan ke rutinitas ini selalu dikirimkan. Di Windows Vista dan versi Windows yang lebih baru, pesan yang diteruskan ke rutinitas ini selalu diberi filter default. Bidang bit penting sama dengan 1 << DPFLTR_INFO_LEVEL, yang 0x00000008. Komponen untuk rutinitas ini adalah DEFAULT. Karena Anda belum mengatur masker filter komponen DEFAULT , masker tersebut memiliki nilai 0x1. Ketika ini adalah ANDed dengan bidang bit penting, hasilnya adalah nol. Jadi pesan keempat tidak dikirimkan.

Buffer DbgPrint dan debugger

Ketika rutinitas DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint, atau KdPrintEx mengirimkan pesan ke debugger, string yang diformat dikirim ke buffer DbgPrint . Konten buffer ini segera ditampilkan di jendela Perintah Debugger, kecuali Anda menonaktifkan tampilan ini dengan menggunakan opsi Buffer DbgPrint Output GFlags.

Selama penelusuran kesalahan kernel lokal, dan di lain waktu tampilan ini telah dinonaktifkan, konten buffer DbgPrint hanya dapat dilihat dengan menggunakan perintah ekstensi !dbgprint .

Setiap panggilan tunggal ke DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint, atau KdPrintEx hanya mengirimkan 512 byte informasi. Output apa pun yang lebih panjang dari 512 byte hilang. Buffer DbgPrint sendiri dapat menyimpan hingga 4 KB data pada build windows gratis, dan hingga 32 KB data pada build Windows yang diperiksa. Pada Windows Server 2003 dan versi Windows yang lebih baru, Anda dapat menggunakan alat KDbgCtrl untuk mengubah ukuran buffer DbgPrint. Alat ini adalah bagian dari Alat Debugging untuk Windows.

Catatan

Build yang diperiksa tersedia pada versi Windows yang lebih lama, sebelum Windows 10 versi 1803. Gunakan alat seperti Driver Verifier dan GFlags untuk memeriksa kode driver di versi Windows yang lebih baru.

Jika pesan difilter karena nilai ComponentId dan Level-nya , pesan tidak dikirimkan di seluruh koneksi penelusuran kesalahan. Oleh karena itu tidak ada cara untuk menampilkan pesan ini di debugger.