Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Procedury DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix i KdPrintEx wysyłają komunikat do debugera jądra w określonych warunkach. Ta procedura umożliwia filtrowanie komunikatów o niskim priorytcie.
Uwaga
W systemach Microsoft Windows Server 2003 i starszych wersjach systemu Windows procedury DbgPrint i KdPrint wysyłają komunikaty do debugera jądra bezwarunkowo. W systemach Windows Vista i nowszych wersjach systemu Windows te procedury warunkowo wysyłają komunikaty, takie jak DbgPrintEx i KdPrintEx. Niezależnie od używanej wersji systemu Windows należy użyć polecenia DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix i KdPrintEx, ponieważ te procedury umożliwiają kontrolowanie warunków, w których jest wysyłany komunikat.
Aby filtrować komunikaty debugowania
Dla każdego komunikatu, który chcesz wysłać do debugera, użyj polecenia DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix lub KdPrintEx w kodzie sterownika. Przekaż odpowiednią nazwę składnika do parametru ComponentId i przekaż wartość do parametru Level , który odzwierciedla ważność lub charakter tego komunikatu. Sam komunikat jest przekazywany do parametrów Format i argumenty przy użyciu tej samej składni co printf.
Ustaw wartość odpowiedniej maski filtru składnika. Każdy składnik ma inną maskę. Wartość maski wskazuje, które komunikaty tego składnika są wyświetlane. Maskę filtru składnika w rejestrze można ustawić przy użyciu edytora rejestru lub w pamięci za pomocą debugera jądra.
Dołącz debuger jądra do komputera. Za każdym razem, gdy sterownik przekazuje komunikat do dbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix lub KdPrintEx, wartości przekazywane do componentId i Level są porównywane z wartością odpowiedniej maski filtru składnika. Jeśli te wartości spełniają określone kryteria, komunikat jest wysyłany do debugera jądra i wyświetlany. W przeciwnym razie nie zostanie wysłana żadna wiadomość.
Uwaga
Wszystkie odwołania na tej stronie do dbgPrintEx mają zastosowanie w równym stopniu do KdPrintEx, vDbgPrintEx i vDbgPrintExWithPrefix.
Identyfikowanie nazwy składnika
Każdy składnik ma oddzielną maskę filtru. Dzięki temu debuger może oddzielnie skonfigurować filtr dla każdego składnika.
Każdy składnik jest określany na różne sposoby, w zależności od kontekstu. W parametrze ComponentIddbgPrintEx nazwa składnika jest poprzedzona prefiksem "DPFLTR_" i sufiksem "_ID". W rejestrze maska filtru składnika ma taką samą nazwę jak sam składnik. W debugerze maska filtru składnika jest poprzedzona prefiksem "Kd_" i sufiksem "_Mask".
Istnieje pełna lista wszystkich nazw składników (w formacie DPFLTR_XXXX_ID) w nagłówku zestawu Microsoft Windows Driver Kit (WDK) dpfilter.h. Większość tych nazw składników jest zarezerwowana dla systemu Windows i sterowników napisanych przez firmę Microsoft.
Istnieją sześć nazw składników zarezerwowanych dla niezależnych dostawców sprzętu. Aby uniknąć mieszania danych wyjściowych sterownika z danymi wyjściowymi składników systemu Windows, należy użyć jednej z następujących nazw składników:
| Nazwa składnika | Typ sterownika |
|---|---|
| IHVVIDEO | Sterownik wideo |
| IHVAUDIO | Sterownik audio |
| IHVNETWORK | Sterownik sieciowy |
| IHVSTREAMING | Sterownik przesyłania strumieniowego jądra |
| IHVBUS | Kierowca autobusu |
| IHVDRIVER | Dowolny inny typ sterownika |
Jeśli na przykład piszesz sterownik wideo, należy użyć DPFLTR_IHVVIDEO_ID jako parametru ComponentIddbgPrintEx, użyć nazwy wartości IHVVIDEO w rejestrze i odwołać się do Kd_IHVVIDEO_Mask w debugerze.
Wszystkie komunikaty wysyłane przez dbgPrint i KdPrint są skojarzone ze składnikiem DEFAULT .
Wybieranie poprawnego poziomu
Parametr Level procedury DbgPrintEx jest typu DWORD. Służy do określania pola bitowego określającego ważność. Połączenie między parametrem Level i tym polem bitowym zależy od rozmiaru Level:
Jeśli poziom jest równy liczbie z zakresu od 0 do 31, włącznie, jest interpretowany jako przesunięcie bitowe. Bitowe pole ważności jest ustawione na wartość jedną <<Poziom. W związku z tym wybranie wartości z zakresu od 0 do 31 dla parametru Level powoduje, że pole bitowe ma dokładnie jeden zestaw bitowy. Jeśli poziom wynosi 0, pole bitowe jest równoważne 0x00000001; Jeśli poziom to 31, pole bitowe jest równoważne 0x80000000.
Jeśli Level jest liczbą z zakresu od 32 do 0xFFFFFFFF włącznie, pole bitowe ważności jest ustawione na wartość samego Level.
W związku z tym, jeśli chcesz ustawić pole bitowe na 0x00004000, możesz określić poziom jako 0x00004000 lub po prostu jako 14. Należy pamiętać, że niektóre wartości pól bitowych nie są możliwe przez ten system — w tym pole bitowe, które jest całkowicie zerowe.
Następujące stałe mogą być przydatne do ustawiania wartości Level. Są one zdefiniowane w nagłówku zestawu Microsoft Windows Driver Kit (WDK) dpfilter.h i nagłówku zestawu 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
Jednym z prostych sposobów użycia parametru Level jest zawsze użycie wartości z zakresu od 0 do 31 — przy użyciu bitów 0, 1, 2, 3 z znaczeniem podanym przez DPFLTR_XXXX_LEVEL i użycie innych bitów w celu oznaczania dowolnego wybranego przez Ciebie znaczenia.
Innym łatwym sposobem użycia parametru Level jest zawsze użycie jawnych pól bitowych. Jeśli wybierzesz tę metodę, możesz chcieć wykonać operację OR wartości DPFLTR_MASK z polem bitowym. Zapewnia to, że przypadkowo nie użyjesz wartości mniejszej niż 32.
Aby sterownik był zgodny ze sposobem korzystania z poziomów komunikatów w systemie Windows, należy ustawić tylko najniższy bit (0x1) pola bitowego ważności, jeśli wystąpi poważny błąd. Jeśli używasz wartości Level mniejszych niż 32, jest to równoznaczne z DPFLTR_ERROR_LEVEL. Jeśli ten bit jest ustawiony, komunikat będzie wyświetlany za każdym razem, gdy ktoś dołączy debuger jądra do komputera, na którym jest uruchomiony sterownik.
Należy używać poziomów ostrzeżeń, śledzenia i informacji w odpowiednich sytuacjach. Inne bity mogą być swobodnie używane do dowolnych celów, które uznasz za przydatne. Dzięki temu można mieć szeroką gamę typów komunikatów, które mogą być selektywnie widoczne lub ukryte.
Wszystkie komunikaty wysyłane przez dbgPrint i KdPrint zachowują się jak komunikaty DbgPrintEx i KdPrintEx z poziomem równym DPFLTR_INFO_LEVEL. Innymi słowy, te komunikaty mają trzeci bit ustawiony w polu bitowym ich ważności.
Ustawianie maski filtru składnika
Istnieją dwa sposoby ustawiania maski filtru składnika:
Dostęp do maski filtru składnika można uzyskać w kluczu rejestru HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. Za pomocą edytora rejestru utwórz lub otwórz ten klucz. W tym kluczu utwórz wartość o nazwie żądanego składnika w wielkiej literze. Ustaw ją na wartość DWORD, którą chcesz wykorzystać jako maskę filtru komponentu.
Jeśli debuger jądra jest aktywny, może uzyskać dostęp do wartości maski filtru składnika, wyłuszając adres przechowywany w symbolu Kd_XXXX_Mask gdzie XXXX jest żądaną nazwą składnika. Wartość tej maski można wyświetlić w WinDbg lub KD za pomocą polecenia dd (Display DWORD), a nową maskę filtru składnika wprowadzić za pomocą polecenia ed (Enter DWORD). Jeśli istnieje niebezpieczeństwo niejednoznaczności symboli, możesz chcieć określić ten symbol jako nt! Kd_XXXX_Mask.
Maski filtrów przechowywane w rejestrze zaczęły obowiązywać podczas rozruchu. Maski filtrów utworzone przez debuger zaczęły obowiązywać natychmiast i utrwalać do momentu ponownego uruchomienia systemu Windows. Wartość ustawiona w rejestrze może zostać zastąpiona przez debuger, ale maska filtru składnika powróci do wartości określonej w rejestrze, jeśli system zostanie uruchomiony ponownie.
Istnieje również maska dla całego systemu o nazwie WIN2000. Jest to domyślnie równe 0x1, ale można go zmienić za pośrednictwem rejestru lub debugera, podobnie jak wszystkie inne składniki. Podczas filtrowania każda maska filtru składników jest najpierw poddawana operacji OR z maską WIN2000. W szczególności oznacza to, że składniki, których maski nigdy nie zostały określone, mają domyślną wartość 0x1.
Kryteria wyświetlania komunikatu
Gdy DbgPrintEx jest wywoływana w kodzie trybu jądra, system Windows porównuje pole bitowe ważności komunikatu określone przez Level z maską filtru składnika określonego przez ComponentId.
Uwaga
Pamiętaj, że gdy parametr Level ma wartość od 0 do 31, pole bitowe ważności jest równe 1 <<poziomowi. Ale gdy parametr Level ma wartość 32 lub większą, pole bitowe ważności jest po prostu równe Level.
System Windows wykonuje operację logiczną AND dla pola bitowego ważności i maski filtrującej składnika. Jeśli wynik nie jestzerowy, komunikat jest wysyłany do debugera.
Przykładowy filtr debugowania
Załóżmy, że przed ostatnim rozruchem utworzono następujące wartości w kluczu Filtr wydruku debugowania :
IHVVIDEO z wartością równą DWORD 0x2
IHVBUS, równe DWORD 0x7FF
Teraz uruchom następujące polecenia w debugerze jądra:
kd> ed Kd_IHVVIDEO_Mask 0x8
kd> ed Kd_IHVAUDIO_Mask 0x7
W tym momencie składnik IHVVIDEO ma maskę filtru 0x8, składnik IHVAUDIO ma maskę filtru 0x7, a składnik IHVBUS ma maskę filtru 0x7FF.
Jednak ponieważ te maski są automatycznie połączone przy użyciu operatora OR z maską systemową WIN2000 (która jest zwykle równa 0x1), maska IHVVIDEO jest skutecznie równa 0x9. Rzeczywiście, składniki, których maski filtrów nie zostały ustawione w ogóle (na przykład IHVSTREAMING lub DEFAULT), będą miały maskę filtru 0x1.
Teraz załóżmy, że w różnych sterownikach występują następujące wywołania funkcji:
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");
Pierwszy komunikat ma parametr Level równy DPFLTR_INFO_LEVEL, czyli 3. Ponieważ jest to mniej niż 32, traktuje się jako przesunięcie bitowe, co skutkuje polem bitowym znaczenia 0x8. Ta wartość jest następnie zastosowana operacja AND z efektywną maską filtrującą składnik IHVVIDEO 0x9, dając wynik niezerowy. Dlatego pierwszy komunikat jest przesyłany do debugera.
Drugi komunikat ma parametr Level równy 7. Ponownie jest to traktowane jako przesunięcie bitowe, co powoduje, że pole bitowe ważności jest równe 0x80. Jest to następnie poddawane operacji AND z maską filtru składnika IHVAUDIO 0x7, co daje wynik równy zero. Więc drugi komunikat nie jest przesyłany.
Trzeci komunikat ma parametr Level równy DPFLTR_MASK | 0x10. Jest to większe niż 31, dlatego pole bitowe ważności jest ustawione na równą wartości Poziomu, czyli 0x80000010. Następnie przeprowadzana jest operacja AND z maską filtru komponentu IHVBUS o wartości 0x7FF, co daje wynik niezerowy. W związku z tym trzeci komunikat jest przesyłany do debugera.
Czwarty komunikat został przekazany do DbgPrint zamiast DbgPrintEx. W systemie Windows Server 2003 i starszych wersjach systemu Windows komunikaty przekazywane do tej procedury są zawsze przesyłane. W systemie Windows Vista i nowszych wersjach systemu Windows komunikaty przekazywane do tej rutyny zawsze otrzymują filtr domyślny. Pole bitowe ważności jest równe 1 << DPFLTR_INFO_LEVEL, co jest 0x00000008. Składnik tej procedury to DEFAULT. Ponieważ nie ustawiono maski filtru składnika DEFAULT , ma wartość 0x1. Gdy to jest zastosowane operatorem AND z polem bitowym ważności, wynik wynosi zero. Tak więc czwarta wiadomość nie jest przesyłana.
Bufor DbgPrint i debugger
Gdy procedury DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint lub KdPrintEx przesyła komunikat do debugera, sformatowany ciąg jest wysyłany do buforu DbgPrint. Zawartość tego buforu zostanie natychmiast wyświetlona w oknie polecenia debugera, chyba że wyłączyłeś tę opcję przy użyciu ustawienia GFlags Opcja DbgPrint buforu dane wyjściowe.
Podczas lokalnego debugowania jądra i za każdym razem, gdy ten ekran został wyłączony, zawartość buforu DbgPrint można wyświetlić tylko za pomocą polecenia rozszerzenia !dbgprint .
Każde pojedyncze wywołanie polecenia DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint lub KdPrintEx przesyła tylko 512 bajtów informacji. Wszystkie dane wyjściowe dłuższe niż 512 bajtów zostaną utracone. Bufor DbgPrint może przechowywać do 4 KB danych w bezpłatnej kompilacji systemu Windows i do 32 KB danych w sprawdzonej kompilacji systemu Windows. W systemie Windows Server 2003 i nowszych wersjach systemu Windows można użyć narzędzia KDbgCtrl, aby zmienić rozmiar buforu DbgPrint. To narzędzie jest częścią narzędzi debugowania dla systemu Windows.
Uwaga
Sprawdzone kompilacje były dostępne w starszych wersjach systemu Windows przed systemem Windows 10 w wersji 1803. Użyj narzędzi, takich jak Driver Verifier i GFlags, aby sprawdzić kod sterownika w nowszych wersjach systemu Windows.
Jeśli komunikat jest filtrowany ze względu na wartości ComponentId i Level , nie jest przesyłany przez połączenie debugowania. W związku z tym nie ma możliwości wyświetlenia tego komunikatu w debugerze.