Compartir a través de


Leer y filtrar mensajes de depuración

Las rutinas DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix y KdPrintEx envían un mensaje al depurador de kernel en condiciones que especifique. Este procedimiento le permite filtrar los mensajes de prioridad baja.

Nota

En Microsoft Windows Server 2003 y versiones anteriores de Windows, las rutinas DbgPrint y KdPrint envían mensajes al depurador de kernel incondicionalmente. En Windows Vista y versiones posteriores de Windows, estas rutinas envían mensajes condicionalmente, como DbgPrintEx y KdPrintEx. Cualquier versión de Windows que use, debe usar DbgPrintEx, vDbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix y KdPrintEx, ya que estas rutinas permiten controlar las condiciones en las que se envía el mensaje.

Para filtrar los mensajes de depuración

  1. Para cada mensaje que quiera enviar al depurador, use DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix o KdPrintEx en el código del controlador. Pase el nombre de componente adecuado al parámetro ComponentId y pase un valor al parámetro Level que refleje la gravedad o la naturaleza de este mensaje. El propio mensaje se pasa a los parámetros Format y arguments mediante la misma sintaxis que printf.

  2. Establezca el valor de la máscara de filtro de componente adecuada. Cada componente tiene una máscara diferente. El valor de máscara indica cuáles de los mensajes de ese componente se muestran. Puede establecer la máscara de filtro de componentes en el Registro mediante un editor del Registro o en memoria mediante un depurador de kernel.

  3. Adjunte un depurador de kernel al equipo. Cada vez que el controlador pasa un mensaje a DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix o KdPrintEx, los valores que se pasan a ComponentId y Level se comparan con el valor de la máscara de filtro de componente correspondiente. Si estos valores cumplen ciertos criterios, el mensaje se envía al depurador del kernel y se muestra. De lo contrario, no se envía ningún mensaje.

Nota

Todas las referencias de esta página a DbgPrintEx se aplican igualmente a KdPrintEx, vDbgPrintEx y vDbgPrintExWithPrefix.

Identificación del nombre del componente

Cada componente tiene una máscara de filtro independiente. Esto permite al depurador configurar el filtro para cada componente por separado.

Cada componente se conoce de maneras diferentes, según el contexto. En el parámetro ComponentId de DbgPrintEx, el nombre del componente tiene el prefijo "DPFLTR_" y tiene el sufijo "_ID". En el Registro, la máscara de filtro de componentes tiene el mismo nombre que el propio componente. En el depurador, la máscara de filtro de componentes tiene el prefijo "Kd_" y tiene el sufijo "_Mask".

Hay una lista completa de todos los nombres de componente (en formato DPFLTR_XXXX_ID) en el encabezado dpfilter.h del Kit de controladores de Microsoft Windows (WDK). La mayoría de estos nombres de componente están reservados para Windows y para controladores escritos por Microsoft.

Hay seis nombres de componente reservados para proveedores de hardware independientes. Para evitar mezclar la salida del controlador con la salida de los componentes de Windows, debe usar uno de los siguientes nombres de componente:

Nombre de componente Tipo de controlador
IHVVIDEO Controlador de vídeo
IHVAUDIO Controlador de audio
IHVNETWORK Controlador de red
IHVSTREAMING Controlador de streaming de kernel
IHVBUS Controlador de autobús
IHVDRIVER Cualquier otro tipo de controlador

Por ejemplo, si está escribiendo un controlador de vídeo, usaría DPFLTR_IHVVIDEO_ID como parámetro ComponentId de DbgPrintEx, use el nombre de valor IHVVIDEO en el registro y consulte Kd_IHVVIDEO_Mask en el depurador.

Todos los mensajes enviados por DbgPrint y KdPrint están asociados al componente DEFAULT .

Elección del nivel correcto

El parámetro Level de la rutina DbgPrintEx es de tipo DWORD. Se usa para determinar el campo de bits de importancia. La conexión entre el parámetro Level y este campo de bits depende del tamaño de Level:

  • Si Level es igual a un número comprendido entre 0 y 31, ambos inclusive, se interpretan como un cambio de bits. El campo de bits de importancia se establece en el valor 1 <<Nivel. Por lo tanto, elegir un valor entre 0 y 31 para Level da como resultado un campo de bits con exactamente un conjunto de bits. Si Level es 0, el campo de bits es equivalente a 0x00000001; si Level es 31, el campo de bits es equivalente a 0x80000000.

  • Si Level es un número comprendido entre 32 y 0xFFFFFFFF inclusivo, el campo de bits de importancia se establece en el valor de Level en sí.

Por lo tanto, si desea establecer el campo de bits en 0x00004000, puede especificar Level como 0x00004000 o simplemente como 14. Tenga en cuenta que este sistema no puede realizar ciertos valores de campo de bits, incluido un campo de bits que es completamente cero.

Las constantes siguientes pueden ser útiles para establecer el valor de Level. Se definen en el encabezado dpfilter.h del Kit de controladores de Microsoft Windows (WDK) y en el encabezado ntrtl.h de Windows SDK:

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

Una manera fácil de usar el parámetro Level es usar siempre valores entre 0 y 31, usando los bits 0, 1, 2, 3 con el significado dado por DPFLTR_XXXX_LEVEL y usando los demás bits para significar lo que elija.

Otra manera fácil de usar el parámetro Level es usar siempre campos de bits explícitos. Si elige este método, puede que desee O el valor DPFLTR_MASK con el campo de bits; esto garantiza que no usará accidentalmente un valor inferior a 32.

Para que el controlador sea compatible con la forma en que Windows usa los niveles de mensaje, solo debe establecer el bit más bajo (0x1) del campo de bits de importancia si se produce un error grave. Si usa valores de nivel inferiores a 32, esto corresponde a DPFLTR_ERROR_LEVEL. Si se establece este bit, el mensaje se va a ver cada vez que alguien adjunta un depurador de kernel a un equipo en el que se ejecuta el controlador.

Los niveles de advertencia, seguimiento e información deben usarse en las situaciones adecuadas. Otros bits se pueden usar libremente para cualquier propósito que encuentre útil. Esto le permite tener una amplia variedad de tipos de mensajes que se pueden ver o ocultar de forma selectiva.

Todos los mensajes enviados por DbgPrint y KdPrint se comportan como mensajes DbgPrintEx y KdPrintEx con Level igual a DPFLTR_INFO_LEVEL. En otras palabras, estos mensajes tienen el tercer bit de su campo de bits de importancia establecido.

Establecimiento de la máscara de filtro de componentes

Hay dos maneras de establecer una máscara de filtro de componentes:

  • Se puede acceder a la máscara de filtro de componentes en la clave del Registro HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. Con un editor del Registro, cree o abra esta clave. En esta clave, cree un valor con el nombre del componente deseado, en mayúsculas. Establézcalo igual al valor DWORD que desea usar como máscara de filtro de componentes.

  • Si un depurador de kernel está activo, puede acceder al valor de máscara de filtro de componentes desreferenciando la dirección almacenada en el símbolo Kd_XXXX_Mask, donde XXXX es el nombre de componente deseado. Puede mostrar el valor de esta máscara en WinDbg o KD con el comando dd (Mostrar DWORD) o escribir una nueva máscara de filtro de componente con el comando ed (Escriba DWORD). Si existe un peligro de ambigüedad de símbolos, es posible que desee especificar este símbolo como nt. Kd_XXXX_Mask.

Las máscaras de filtro almacenadas en el registro surten efecto durante el arranque. Las máscaras de filtro creadas por el depurador surten efecto inmediatamente y persistan hasta que se reinicie Windows. El depurador puede invalidar un valor establecido en el Registro, pero la máscara de filtro de componentes devolverá al valor especificado en el registro si se reinicia el sistema.

También hay una máscara para todo el sistema denominada WIN2000. Esto es igual a 0x1 de forma predeterminada, aunque se puede cambiar a través del Registro o del depurador, como todos los demás componentes. Al realizar el filtrado, cada máscara de filtro de componentes es primero ORed con la máscara de WIN2000 . En concreto, esto significa que los componentes cuyas máscaras nunca se han especificado de forma predeterminada para 0x1.

Criterios para mostrar el mensaje

Cuando se llama a DbgPrintEx en el código en modo kernel, Windows compara el campo de bits de importancia del mensaje especificado por Level con la máscara de filtro del componente especificado por ComponentId.

Nota

Recuerde que cuando el parámetro Level está comprendido entre 0 y 31, el campo de bits de importancia es igual a 1 <<Nivel. Pero cuando el parámetro Level es 32 o superior, el campo de bits de importancia es simplemente igual a Level.

Windows realiza una operación AND en el campo bit de importancia y la máscara de filtro de componentes. Si el resultado es distinto de cero, el mensaje se envía al depurador.

Ejemplo de filtro de depuración

Supongamos que antes del último arranque, ha creado los siguientes valores en la clave Depurar filtro de impresión :

  • IHVVIDEO, con un valor igual a DWORD 0x2

  • IHVBUS, igual que DWORD 0x7FF

Ahora emite los siguientes comandos en el depurador de kernel:

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

En este momento, el componente IHVVIDEO tiene una máscara de filtro de 0x8, el componente IHVAUDIO tiene una máscara de filtro de 0x7 y el componente IHVBUS tiene una máscara de filtro de 0x7FF.

Sin embargo, dado que estas máscaras son automáticamente ORed con la máscara de todo el sistema WIN2000 (que normalmente es igual a 0x1), la máscara IHVVIDEO es eficazmente igual a 0x9. De hecho, los componentes cuyas máscaras de filtro no se han establecido en absoluto (por ejemplo, IHVSTREAMING o DEFAULT) tendrán una máscara de filtro de 0x1.

Ahora supongamos que las siguientes llamadas de función se producen en varios controladores:

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");

El primer mensaje tiene su parámetro Level igual a DPFLTR_INFO_LEVEL, que es 3. Dado que esto es menor que 32, se trata como un cambio de bits, lo que da lugar a un campo de bits de importancia de 0x8. A continuación, este valor se andida con la máscara de filtro del componente IHVVIDEO efectiva de 0x9, lo que proporciona un resultado distinto de cero. Por lo tanto, el primer mensaje se transmite al depurador.

El segundo mensaje tiene su parámetro Level igual a 7. De nuevo, esto se trata como un desplazamiento de bits, lo que da lugar a un campo de bits de importancia de 0x80. A continuación, se usa ANDed con la máscara de filtro del componente IHVAUDIO de 0x7, lo que da un resultado de cero. Por lo tanto, no se transmite el segundo mensaje.

El tercer mensaje tiene su parámetro Level igual a DPFLTR_MASK | 0x10. Esto es mayor que 31 y, por lo tanto, el campo de bits de importancia se establece igual al valor de Level ( es decir, en 0x80000010. A continuación, se usa ANDed con la máscara de filtro del componente IHVBUS de 0x7FF, lo que proporciona un resultado distinto de cero. Por lo tanto, el tercer mensaje se transmite al depurador.

El cuarto mensaje se pasó a DbgPrint en lugar de DbgPrintEx. En Windows Server 2003 y versiones anteriores de Windows, los mensajes pasados a esta rutina siempre se transmiten. En Windows Vista y versiones posteriores de Windows, los mensajes pasados a esta rutina siempre reciben un filtro predeterminado. El campo de bits de importancia es igual a 1 << DPFLTR_INFO_LEVEL, que es 0x00000008. El componente de esta rutina es DEFAULT. Puesto que no ha establecido la máscara de filtro del componente DEFAULT , tiene un valor de 0x1. Cuando se trata de ANDed con el campo de bits de importancia, el resultado es cero. Por lo tanto, el cuarto mensaje no se transmite.

Búfer dbgPrint y el depurador

Cuando la rutina DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint o KdPrintEx transmite un mensaje al depurador, la cadena con formato se envía al búfer dbgPrint . El contenido de este búfer se muestra inmediatamente en la ventana Comando del depurador, a menos que deshabilite esta presentación mediante la opción De salida DbgPrint de Buffer de GFlags.

Durante la depuración del kernel local y en cualquier otro momento en que se haya deshabilitado esta pantalla, el contenido del búfer dbgPrint solo se puede ver mediante el comando de extensión !dbgprint .

Cualquier llamada única a DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint o KdPrintEx transmite solo 512 bytes de información. Se pierde cualquier salida de más de 512 bytes. El propio búfer DbgPrint puede contener hasta 4 KB de datos en una compilación gratuita de Windows y hasta 32 KB de datos en una compilación comprobada de Windows. En Windows Server 2003 y versiones posteriores de Windows, puede usar la herramienta KDbgCtrl para modificar el tamaño del búfer dbgPrint. Esta herramienta forma parte de herramientas de depuración para Windows.

Nota

Las compilaciones comprobadas estaban disponibles en versiones anteriores de Windows, antes de Windows 10 versión 1803. Use herramientas como Comprobador de controladores y GFlags para comprobar el código de controlador en versiones posteriores de Windows.

Si se filtra un mensaje debido a sus valores ComponentId y Level , no se transmite a través de la conexión de depuración. Por lo tanto, no hay ninguna manera de mostrar este mensaje en el depurador.