Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
As rotinas DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix e KdPrintEx enviam uma mensagem para o depurador do kernel sob condições que você especificar. Este procedimento permite filtrar mensagens de baixa prioridade.
Observação
No Microsoft Windows Server 2003 e versões anteriores do Windows, as rotinas DbgPrint e KdPrint enviam mensagens para o depurador do kernel incondicionalmente. No Windows Vista e versões posteriores do Windows, essas rotinas enviam mensagens condicionalmente, como DbgPrintEx e KdPrintEx. Seja qual for a versão do Windows que você estiver usando, você deve usar DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix e KdPrintEx, porque essas rotinas permitem controlar as condições sob as quais a mensagem é enviada.
Para filtrar mensagens de depuração
Para cada mensagem que você deseja enviar para o depurador, use DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix ou KdPrintEx no código do driver. Passe o nome do componente apropriado para o parâmetro ComponentId e passe um valor para o parâmetro Level que reflita a gravidade ou a natureza dessa mensagem. A mensagem em si é passada para os parâmetros Format e arguments usando a mesma sintaxe de printf.
Defina o valor da máscara de filtro de componente apropriada. Cada componente tem uma máscara diferente. O valor da máscara indica quais mensagens desse componente são exibidas. Você pode definir a máscara de filtro do componente no registo usando um editor de registo ou diretamente na memória usando um depurador de kernel.
Anexe um depurador do kernel ao computador. Sempre que o driver passa uma mensagem para DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix ou KdPrintEx, os valores que são passados para ComponentId e Level são comparados com o valor da máscara de filtro de componente correspondente. Se esses valores satisfizerem determinados critérios, a mensagem será enviada para o depurador do kernel e exibida. Caso contrário, nenhuma mensagem será enviada.
Observação
Todas as referências nesta página a DbgPrintEx aplicam-se igualmente a KdPrintEx, vDbgPrintEx e vDbgPrintExWithPrefix.
Identificando o nome do componente
Cada componente tem uma máscara de filtro separada. Isso permite que o depurador configure o filtro para cada componente separadamente.
Cada componente é referido de maneiras diferentes, dependendo do contexto. No parâmetro ComponentId de DbgPrintEx, o nome do componente é prefixado com "DPFLTR_" e sufixo com "_ID". No Registro, a máscara de filtro do componente tem o mesmo nome que o próprio componente. No depurador, a máscara de filtro do componente é prefixada com "Kd_" e sufixada com "_Mask".
Há uma lista completa de todos os nomes de componentes (no formato DPFLTR_XXXX_ID) no cabeçalho do Microsoft Windows Driver Kit (WDK) dpfilter.h. A maioria desses nomes de componentes são reservados para o Windows e para drivers escritos pela Microsoft.
Há seis nomes de componentes reservados para fornecedores independentes de hardware. Para evitar misturar a saída do driver com a saída de componentes do Windows, você deve usar um dos seguintes nomes de componentes:
| Nome do componente | Tipo de controlador |
|---|---|
| IHVVIDEO | Driver de vídeo |
| IHVAUDIO | Controlador de áudio |
| IHVNETWORK | Controlador de rede |
| IHVSTREAMING | Driver de streaming do kernel |
| IHVBUS | Motorista de ônibus |
| IHVDRIVER | Qualquer outro tipo de condutor |
Por exemplo, se você estiver escrevendo um driver de vídeo, você usaria DPFLTR_IHVVIDEO_ID como o parâmetro ComponentId de DbgPrintEx, use o nome do valor IHVVIDEO no registro e consulte Kd_IHVVIDEO_Mask no depurador.
Todas as mensagens enviadas por DbgPrint e KdPrint estão associadas ao componente DEFAULT .
Escolhendo o nível correto
O parâmetro Level da rotina DbgPrintEx é do tipo DWORD. É utilizado para determinar o campo de bits de importância. A conexão entre o parâmetro Level e este campo de bit depende do tamanho de Level:
Se Level é igual a um número entre 0 e 31, inclusive, é interpretado como um bit shift. O campo bit de importância é definido como o valor 1 <<Level. Assim, escolher um valor entre 0 e 31 para Level resulta em um campo de bits com exatamente um bit definido. Se Level for 0, o campo bit será equivalente a 0x00000001; se Level for 31, o campo bit será equivalente a 0x80000000.
Se Level for um número entre 32 e 0xFFFFFFFF inclusive, o campo bit de importância será definido como o valor de Level em si.
Assim, se você deseja definir o campo bit como 0x00004000, você pode especificar Level como 0x00004000 ou simplesmente como 14. Observe que certos valores de campo de bit não são possíveis por este sistema -- incluindo um campo de bit que é totalmente zero.
As constantes a seguir podem ser úteis para definir o valor de Level. Eles são definidos no cabeçalho do Microsoft Windows Driver Kit (WDK) dpfilter.h e no cabeçalho do 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
Uma maneira fácil de usar o parâmetro Level é sempre usar valores entre 0 e 31 -- usando os bits 0, 1, 2, 3 com o significado dado por DPFLTR_XXXX_LEVEL, e usando os outros bits para significar o que você escolher.
Outra maneira fácil de usar o parâmetro Level é sempre usar campos de bits explícitos. Se escolher este método, podes querer OU o valor DPFLTR_MASK com o teu campo de bits; isso garante que não utilizarás acidentalmente um valor inferior a 32.
Para tornar o driver compatível com a maneira como o Windows usa os níveis de mensagem, deve-se definir apenas o bit mais baixo (0x1) do campo de bits de importância, se um erro grave ocorrer. Se você estiver usando valores de nível inferiores a 32, isso corresponde a DPFLTR_ERROR_LEVEL. Se esse bit estiver definido, sua mensagem será visualizada sempre que alguém anexar um depurador do kernel a um computador no qual o driver está sendo executado.
Os níveis de aviso, rastreio e informação devem ser utilizados nas situações adequadas. Outros bits podem ser usados livremente para quaisquer fins que você achar úteis. Isso permite que você tenha uma grande variedade de tipos de mensagens que podem ser vistas seletivamente ou ocultadas.
Todas as mensagens enviadas por DbgPrint e KdPrint se comportam como mensagens DbgPrintEx e KdPrintEx com Nível igual a DPFLTR_INFO_LEVEL. Em outras palavras, essas mensagens têm o terceiro bit de seu campo de bit de importância definido.
Definindo a máscara de filtro de componente
Há duas maneiras de definir uma máscara de filtro de componente:
A máscara de filtro de componente pode ser acessada na chave do Registro HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. Usando um editor do Registro, crie ou abra essa chave. Sob essa chave, crie um valor com o nome do componente desejado, em maiúsculas. Defina-o igual ao valor DWORD que você deseja usar como a máscara de filtro do componente.
Se um depurador do kernel estiver ativo, ele poderá acessar o valor da máscara de filtro do componente desreferenciando o endereço armazenado no símbolo Kd_XXXX_Mask, ondeXXXX é o nome do componente desejado. Você pode exibir o valor dessa máscara no WinDbg ou KD com o comando dd (Display DWORD) ou inserir uma nova máscara de filtro de componente com o comando ed (Enter DWORD ). Se houver um perigo de ambiguidade do símbolo, você pode especificar este símbolo como nt! Kd_XXXX_Mask.
As máscaras de filtro armazenadas no Registro entram em vigor durante a inicialização. As máscaras de filtro criadas pelo depurador entram em vigor imediatamente e persistem até que o Windows seja reinicializado. Um valor definido no registro pode ser substituído pelo depurador, mas a máscara de filtro do componente retornará ao valor especificado no registro se o sistema for reinicializado.
Há também uma máscara em todo o sistema chamada WIN2000. Isso é igual a 0x1 por padrão, embora, como todos os outros componentes, possa ser alterado através do registo ou do depurador. Quando a filtragem é executada, cada máscara de filtro de componente é primeiro combinada através de um OU lógico com a máscara WIN2000. Em particular, isso significa que os componentes cujas máscaras nunca foram especificadas têm como padrão 0x1.
Critérios para exibir a mensagem
Quando DbgPrintEx é chamado no código de modo kernel, o Windows compara o campo de bit de importância da mensagem especificado por Level com a máscara de filtro do componente especificado por ComponentId.
Observação
Lembre-se de que quando o parâmetro Level está entre 0 e 31, o campo de bits de importância é igual a 1 <<Level. Mas quando o parâmetro Level é 32 ou superior, a importância bitfield é simplesmente igual a Level.
O Windows executa uma operação AND no campo de bits de importância e na máscara de filtragem de componente. Se o resultado for diferente de zero, a mensagem será enviada para o depurador.
Exemplo de filtro de depuração
Suponha que antes da última inicialização, você criou os seguintes valores na chave Debug Print Filter :
IHVVIDEO, com um valor igual a DWORD 0x2
IHVBUS, igual a DWORD 0x7FF
Agora você emite os seguintes comandos no depurador do kernel:
kd> ed Kd_IHVVIDEO_Mask 0x8
kd> ed Kd_IHVAUDIO_Mask 0x7
Neste ponto, o componente IHVVIDEO tem uma máscara de filtro de 0x8, o componente IHVAUDIO tem uma máscara de filtro de 0x7 e o componente IHVBUS tem uma máscara de filtro de 0x7FF.
No entanto, como essas máscaras são automaticamente combinadas com a máscara WIN2000 a nível do sistema (que geralmente é igual a 0x1) através da operação lógica OR, a máscara IHVVIDEO é efetivamente igual a 0x9. Na verdade, os componentes cujas máscaras de filtro não foram definidas (por exemplo, IHVSTREAMING ou DEFAULT) terão uma máscara de filtro de 0x1.
Agora suponha que as seguintes chamadas de função ocorrem em vários drivers:
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");
A primeira mensagem tem seu parâmetro Level igual a DPFLTR_INFO_LEVEL, que é 3. Uma vez que este é menor que 32, é tratado como um deslocamento de bits, resultando em um campo de bits importante de 0x8. Esse valor é então combinado com a máscara de filtro eficaz do componente IHVVIDEO de 0x9, resultando num valor diferente de zero. Assim, a primeira mensagem é transmitida ao depurador.
A segunda mensagem tem seu parâmetro Level igual a 7. Mais uma vez, isso é tratado como um deslocamento de bit, resultando em um campo de bit de importância de 0x80. Isso é então combinado com a máscara de filtro do componente IHVAUDIO de 0x7, resultando em zero. Assim, a segunda mensagem não é transmitida.
A terceira mensagem tem seu parâmetro Level igual a DPFLTR_MASK | 0x10. Isso é maior que 31 e, portanto, o campo de bit de importância é definido igual ao valor de Level -- em outras palavras, para 0x80000010. É então realizada uma operação lógica AND com a máscara de filtro de componente IHVBUS de 0x7FF, resultando em um valor diferente de zero. Assim, a terceira mensagem é transmitida ao depurador.
A quarta mensagem foi passada para DbgPrint em vez de DbgPrintEx. No Windows Server 2003 e em versões anteriores do Windows, as mensagens passadas para esta rotina são sempre transmitidas. No Windows Vista e versões posteriores do Windows, as mensagens passadas para essa rotina sempre recebem um filtro padrão. O campo bit de importância é igual a 1 << DPFLTR_INFO_LEVEL, que é 0x00000008. O componente para essa rotina é DEFAULT. Como você não definiu a máscara de filtro do componente DEFAULT , ela tem um valor de 0x1. Quando isso é combinado com o campo de bits de importância, o resultado é zero. Assim, a quarta mensagem não é transmitida.
Buffer DbgPrint e o depurador
Quando a rotina DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint ou KdPrintEx transmite uma mensagem para o depurador, a cadeia de caracteres formatada é enviada para o buffer DbgPrint. O conteúdo desse buffer é exibido imediatamente na janela de comando do depurador, a menos que você desabilite essa exibição usando a opção Buffer DbgPrint Output do GFlags.
Durante a depuração do kernel local e em qualquer outra ocasião em que esta exibição tenha sido desativada, o conteúdo do buffer DbgPrint só pode ser visualizado usando o comando !dbgprint extension.
Qualquer chamada única para DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint ou KdPrintEx transmite apenas 512 bytes de informações. Qualquer saída maior que os 512 bytes é perdida. O buffer DbgPrint em si pode armazenar até 4 KB de dados em uma compilação gratuita do Windows e até 32 KB de dados em uma compilação verificada do Windows. No Windows Server 2003 e versões posteriores do Windows, você pode usar a ferramenta KDbgCtrl para alterar o tamanho do buffer DbgPrint. Esta ferramenta faz parte das Ferramentas de Depuração para Windows.
Observação
As compilações verificadas estavam disponíveis em versões mais antigas do Windows, antes do Windows 10 versão 1803. Use ferramentas como o Verificador de Driver e GFlags para verificar o código do driver em versões posteriores do Windows.
Se uma mensagem for filtrada devido aos seus valores ComponentId e Level , ela não será transmitida pela conexão de depuração. Portanto, não há nenhuma maneira de exibir essa mensagem no depurador.