Laboratorio paso a paso de controladores de Windows de depuración (modo kernel eco)
En este laboratorio se presenta el depurador de kernel de WinDbg. Use WinDbg para depurar el código del controlador de ejemplo del modo kernel de eco.
Objetivos del laboratorio
Este laboratorio incluye ejercicios que presentan las herramientas de depuración, enseñan comandos de depuración comunes, ilustran el uso de puntos de interrupción y muestran cómo usar las extensiones de depuración.
En este laboratorio, usará una conexión de depuración de kernel activa para explorar las siguientes acciones:
- Uso de los comandos del depurador de Windows
- Uso de comandos estándar (pilas de llamadas, variables, subprocesos, IRQL)
- Uso de comandos de depuración de controladores avanzados (!commands)
- Uso de símbolos
- Establecimiento de puntos de interrupción en la depuración en tiempo real
- Visualización de las pilas de llamadas
- Visualización del árbol de dispositivos Plug and Play
- Trabajo con el contexto de subprocesos y procesos
Depuración en modo de usuario y kernel
Al trabajar con el depurador de Windows, puede realizar dos tipos de depuración:
Modo de usuario: las aplicaciones y subsistemas se ejecutan en el equipo en modo de usuario. Los procesos que se ejecutan en modo de usuario lo hacen dentro de sus propios espacios de direcciones virtuales. Están restringidos a obtener acceso directo a muchas partes del sistema, incluido el hardware del sistema, la memoria que no está asignada para su uso y otras partes del sistema que podrían poner en peligro la integridad del sistema. Dado que los procesos que se ejecutan en modo de usuario están aislados eficazmente del sistema y de otros procesos en modo de usuario, no pueden interferir con estos recursos.
Modo kernel: el sistema operativo y los programas con privilegios se ejecutan en modo kernel. El código en modo kernel tiene permiso para acceder a cualquier parte del sistema. No está restringido como el código en modo de usuario. Puede obtener acceso a cualquier parte de cualquier otro proceso que se ejecute en modo de usuario o en modo kernel. Gran parte de la funcionalidad principal del sistema operativo y muchos controladores de dispositivos de hardware se ejecutan en modo kernel.
En este ejercicio se tratan los comandos de depuración que se usan con frecuencia durante la depuración en modo de usuario y en modo kernel. En el ejercicio también se tratan las extensiones de depuración (a veces denominadas "bang" !commands) que se usan para la depuración en modo kernel.
Configuración del laboratorio
Necesita el siguiente hardware para completar el laboratorio:
- Un equipo portátil o de escritorio (host) que ejecute Windows 10
- Un segundo equipo portátil o de escritorio (destino) que ejecute Windows 10
- Un concentrador de red o enrutador y cables de red para conectar los dos equipos
- Acceso a Internet para descargar archivos de símbolos
Necesita el siguiente software para completar el laboratorio:
- Visual Studio
- Kit de desarrollo de software de Windows (SDK) para Windows 10
- Kit de controladores de Windows (WDK) para Windows 10
- Controlador de eco de ejemplo para Windows 10
El laboratorio incluye las secciones siguientes:
- Conexión a una sesión WinDbg en modo kernel
- Comandos y técnicas de depuración en modo kernel
- Descarga y compilación del controlador de eco KMDF
- Instalación del ejemplo de controlador de eco en el sistema de destino
- Uso de WinDbg para mostrar información sobre el controlador
- Visualización de la información del árbol de dispositivos Plug and Play
- Trabajo con puntos de interrupción y código fuente
- Visualización de variables y pilas de llamadas
- Visualización de procesos y subprocesos
- IRQL, registros y finalización de la sesión de WinDbg
- Recursos de depuración de Windows
Conexión a una sesión WinDbg en modo kernel
En esta sección, configurará la depuración de red en el sistema host y de destino.
Los equipos de este laboratorio deben configurarse para usar una conexión de red Ethernet para la depuración del kernel.
Este laboratorio usa dos equipos. El depurador de Windows se ejecuta en el sistema host y el controlador de eco del marco de controladores del modo kernel (KMDF) se ejecuta en el sistema de destino.
Use un concentrador de red o enrutador y cables de red para conectar los dos equipos.
Para trabajar con aplicaciones en modo kernel y usar WinDbg, se recomienda usar KDNET a través del transporte Ethernet. Para obtener información sobre cómo usar el protocolo de transporte Ethernet, consulte Introducción a WinDbg (modo kernel). Para obtener más información sobre cómo configurar el equipo de destino, consulte Preparación de un equipo para la implementación manual del controlador y Configuración de la depuración automática del kernel de red KDNET.
Configuración de la depuración en modo kernel mediante Ethernet
Para habilitar la depuración en modo kernel en el sistema de destino:
En el sistema host, abra una ventana de símbolo del sistema y escriba ipconfig para determinar su dirección IPv4.
Windows IP Configuration Ethernet adapter Ethernet: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b%3 Autoconfiguration IPv4 Address. . : 169.182.1.1 Subnet Mask . . . . . . . . . . . : 255.255.0.0 Default Gateway . . . . . . . . . :
Registre la dirección IP del sistema host: ______________________________________
En el sistema de destino, abra una ventana de símbolo del sistema y use el comando
ping
para confirmar la conectividad de red entre los dos sistemas.ping 169.182.1.1
Use la dirección IP real del sistema host que registró en lugar de 169.182.1.1 que se muestra en la salida de ejemplo.
Pinging 169.182.1.1 with 32 bytes of data: Reply from 169.182.1.1: bytes=32 time=1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Ping statistics for 169.182.1.1: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 1ms, Average = 0ms
Para habilitar la depuración en modo kernel en el sistema de destino, siga los pasos siguientes.
Importante
Antes de usar BCDEdit para cambiar la información de arranque, es posible que deba suspender temporalmente las características de seguridad de Windows, como BitLocker y Arranque seguro, en el equipo de prueba. Vuelva a habilitar estas características de seguridad cuando se completen las pruebas. Administre correctamente el equipo de prueba cuando las características de seguridad estén deshabilitadas. El arranque seguro normalmente está deshabilitado en UEFI. Para acceder a la configuración de UEFI, vaya a Sistema, Recuperación, Inicio avanzado. Después, seleccione Solucionar problemas, Opciones avanzadas, Configuración de firmware de UEFI. Tenga cuidado, ya que establecer incorrectamente las opciones de UEFI o deshabilitar BitLocker, puede hacer que el sistema sea inoperable.
En el equipo de destino, abra una ventana de símbolo del sistema como administrador. Escriba este comando para habilitar la depuración:
bcdedit /set {default} DEBUG YES
Escriba este comando para habilitar la firma de pruebas:
bcdedit /set TESTSIGNING ON
Escriba este comando para establecer la dirección IP del sistema host. Utilice la dirección IP del sistema host que registró anteriormente, no la que se muestra.
bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Advertencia
Para aumentar la seguridad de la conexión y reducir el riesgo de las solicitudes de conexión aleatorias del depurador de cliente, use una clave aleatoria generada automáticamente. Para obtener más información, consulte Configuración de la depuración automática del kernel de red KDNET.
Escriba este comando para confirmar que los valores de
dbgsettings
se han establecido correctamente:bcdedit /dbgsettings
key 2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p debugtype NET hostip 169.168.1.1 port 50000 dhcp Yes The operation completed successfully.
Nota:
Si recibe un mensaje del firewall y desea usar el depurador, marque las tres casillas.
En el equipo host, abra una ventana de símbolo del sistema como administrador. En este laboratorio usaremos la versión x64 de WinDbg.exe del Kit para controladores de Windows (WDK) que se instaló como parte de la instalación del kit de Windows. Cambie al directorio de WinDbg predeterminado; la ubicación predeterminada se muestra a continuación.
cd C:\Program Files(x86)\Windows Kits\10\Debuggers\x64
En estos laboratorios se supone que ambos equipos ejecutan una versión de 64 bits de Windows tanto en el destino como en el host. Si no es así, el mejor enfoque es ejecutar el mismo bit de herramientas en el host en el que se ejecuta el destino. Por ejemplo, si el destino ejecuta Windows de 32 bits, ejecute una versión de 32 bits del depurador en el host. Para obtener más información, consulte Elección de herramientas de depuración de 32 o 64 bits.
Abra WinDbg con depuración de usuario remoto mediante el siguiente comando. Los valores de la clave y el puerto coinciden con los valores establecidos anteriormente mediante BCDEdit en el equipo de destino.
WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Reinicie el sistema de destino.
En un minuto o dos, la salida de depuración debe mostrarse en el sistema host.
Microsoft (R) Windows Debugger Version 10.0.17074.1002 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. Using NET for debugging Opened WinSock 2.0 Waiting to reconnect... Connected to target 169.182.1.1 on port 50005 on local IP 169.182.1.2 You can get the target MAC address by running .kdtargetmac command. Connected to Windows 10 16299 x64 target at (Wed Feb 28 17:16:23.051 2018 (UTC - 8:00)), ptr64 TRUE Kernel Debugger connection established. (Initial Breakpoint requested) Symbol search path is: srv* Executable search path is: Windows 10 Kernel Version 16299 MP (4 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Built by: 16299.15.amd64fre.rs3_release.170928-1534 Machine Name: Kernel base = 0xfffff800`9540d000 PsLoadedModuleList = 0xfffff800`95774110 Debug session time: Wed Feb 28 17:16:23.816 2018 (UTC - 8:00) System Uptime: 0 days 0:00:20.534
La ventana Comando del depurador es la ventana de información de depuración principal en WinDbg. Puede escribir comandos del depurador y ver la salida del comando en esta ventana.
La ventana Comando del depurador se divide en dos paneles. Los comandos se escriben en el panel más pequeño, que es el panel de entrada de comandos, en la parte inferior de la ventana y la salida del comando se ve en el panel más grande de la parte superior de la ventana.
En el panel de entrada de comandos, use las teclas de flecha arriba y flecha abajo para desplazarse por el historial de comandos. Cuando aparezca un comando, puede editarlo o pulsar Entrar para ejecutar el comando.
Comandos y técnicas de depuración en modo kernel
En esta sección, usará comandos de depuración para mostrar información sobre el sistema de destino.
Algunos comandos de depuración muestran texto mediante el lenguaje de marcado del depurador (DML) que puede seleccionar para recopilar rápidamente más información.
En el sistema host, use Ctrl+Bloq Despl en WinDBg para irrumpir en el código que se ejecuta en el sistema de destino. El sistema de destino puede tardar algún tiempo en responder.
Escriba el siguiente comando para habilitar DML en la ventana Comando del depurador:
0: kd> .prefer_dml 1 DML versions of commands on by default
Puede acceder a la ayuda del comando de referencia mediante el comando
.hh
. Escriba el siguiente comando para ver la ayuda de referencia de comandos para.prefer_dml
:0: kd> .hh .prefer_dml
El archivo de ayuda del depurador muestra ayuda para el comando
.prefer_dml
.Para visualizar información detallada de la versión en el sistema de destino, escriba el comando vertarget (Mostrar versión del equipo de destino) en la ventana WinDbg:
0: kd> vertarget Windows 10 Kernel Version 9926 MP (4 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Built by: 9926.0.amd64fre.fbl_awesome1501.150119-1648 Machine Name: "" Kernel base = 0xfffff801`8d283000 PsLoadedModuleList = 0xfffff801`8d58aef0 Debug session time: Fri Feb 20 10:15:17.807 2015 (UTC - 8:00) System Uptime: 0 days 01:31:58.931
Para comprobar que está trabajando con el proceso correcto en modo kernel, escriba el comando lm (Enumerar módulos cargados) en la ventana WinDbg para mostrar los módulos cargados:
0: Kd> lm start end module name fffff801`09200000 fffff801`0925f000 volmgrx (no symbols) fffff801`09261000 fffff801`092de000 mcupdate_GenuineIntel (no symbols) fffff801`092de000 fffff801`092ec000 werkernel (export symbols) werkernel.sys fffff801`092ec000 fffff801`0934d000 CLFS (export symbols) CLFS.SYS fffff801`0934d000 fffff801`0936f000 tm (export symbols) tm.sys fffff801`0936f000 fffff801`09384000 PSHED (export symbols) PSHED.dll fffff801`09384000 fffff801`0938e000 BOOTVID (export symbols) BOOTVID.dll fffff801`0938e000 fffff801`093f7000 spaceport (no symbols) fffff801`09400000 fffff801`094cf000 Wdf01000 (no symbols) fffff801`094d9000 fffff801`09561000 CI (export symbols) CI.dll ...
La salida que se ha omitido se indica con "..." en este laboratorio.
Para solicitar información detallada sobre un módulo específico, use la opción
v
(detallada):0: Kd> lm v m tcpip Browse full module list start end module name fffff801`09eeb000 fffff801`0a157000 tcpip (no symbols) Loaded symbol image file: tcpip.sys Image path: \SystemRoot\System32\drivers\tcpip.sys Image name: tcpip.sys Browse all global symbols functions data Timestamp: Sun Nov 09 18:59:03 2014 (546029F7) CheckSum: 00263DB1 ImageSize: 0026C000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 Unable to enumerate user-mode unloaded modules, Win32 error 0n30
No hay ninguna ruta de acceso de símbolo establecida ni símbolos cargados, por lo que la información que está disponible en el depurador es limitada.
Descarga y compilación del controlador de eco KMDF
En esta sección, descargará y compilará el controlador de eco KMDF.
Normalmente, trabajaría con su propio código de controlador al usar WinDbg. Para familiarizarse con la operación WinDbg, este laboratorio usa el controlador de ejemplo de plantilla "Eco" de KMDF. El código fuente está disponible para ayudar a comprender la información que se muestra en WinDbg. Este ejemplo también se utiliza para ilustrar cómo se puede recorrer paso a paso el código nativo en modo kernel. Esta técnica puede ser valiosa para depurar problemas complejos de código en modo kernel.
Para descargar y compilar el controlador de audio de ejemplo eco:
Descargue y extraiga el ejemplo de eco de KMDF de GitHub.
Vea el ejemplo de eco en GitHub.
Obtenga información sobre el ejemplo.
El ejemplo de eco de KMDF se encuentra en la carpeta general.
Descargue los ejemplos de controladores en un archivo zip: Ejemplos de controladores
Descargue el archivo zip en la unidad de disco duro local.
Seleccione y mantenga pulsado (o haga clic con el botón derecho) el archivo zip y seleccione Extraer todo. Especifique una nueva carpeta o vaya a una existente para almacenar los archivos extraídos. Por ejemplo, podría especificar C:\DriverSamples\ como la nueva carpeta en la que extraer los archivos.
Una vez extraídos los archivos, vaya a la subcarpeta siguiente: C:\DriverSamples\general\echo\kmdf
En Microsoft Visual Studio, seleccione Archivo>Abrir>Proyecto/Solución... y vaya a la carpeta que contiene los archivos extraídos, por ejemplo, C:\DriverSamples\general\echo\kmdf. Haga doble clic en el archivo de solución kmdfecho para abrirlo.
En Visual Studio, localice el Explorador de soluciones. Si esta ventana aún no está abierta, seleccione Explorador de soluciones en el menú Ver. En el Explorador de soluciones, puede ver una solución que tiene tres proyectos.
Establezca la configuración y la plataforma del ejemplo. En el Explorador de soluciones, seleccione y mantenga pulsada (o haga clic con el botón derecho) la Solución "kmdfecho" (3 proyectos) y seleccione Administrador de configuración. Asegúrese de que la configuración y las opciones de plataforma sean las mismas para los tres proyectos. De forma predeterminada, la configuración se establece en Win10 Debug y la plataforma se establece en Win64 para todos los proyectos. Si realiza algún cambio de configuración o plataforma para un proyecto, debe realizar los mismos cambios para los tres proyectos restantes.
Los ejemplos de controladores deben modificarse para usar valores que no se superpongan con los controladores existentes. Consulte De código de ejemplo a controlador de producción: qué cambiar en los ejemplos para obtener información sobre cómo crear un ejemplo de controlador único que coexista con los controladores reales existentes instalados en Windows.
Establezca la biblioteca en tiempo de ejecución. Abra la página de propiedades del controlador de eco y busque C/C++>Generación de código. Cambie la biblioteca en tiempo de ejecución a Depuración multiproceso (/MTd). Para obtener más información sobre las opciones de compilación, consulte /MD, /MT, /LD (Uso de la biblioteca en tiempo de ejecución).
En las propiedades del controlador, asegúrese de que Firma de controladores>Modo de firma esté establecido en Firma de prueba.
En Visual Studio, seleccione Compilar>Compilar solución.
Las ventanas de compilación deberían mostrar un mensaje indicando que la compilación se ha realizado correctamente para los tres proyectos.
Sugerencia
Si encuentra un mensaje de error de compilación, use el número de error de compilación para determinar una corrección. Por ejemplo, el error MSBuild MSB8040 describe cómo trabajar con bibliotecas con mitigación de Spectre.
En el Explorador de archivos, vaya a la carpeta que contiene los archivos extraídos para el ejemplo. Por ejemplo, vaya a C:\DriverSamples\general\echo\kmdf, si es la carpeta que especificó anteriormente. Dentro de esa carpeta, la ubicación de los archivos de controlador compilados varía en función de la configuración y de los ajustes de la plataforma que seleccionó en Administrador de configuración. Si dejó la configuración predeterminada sin cambios, los archivos de controlador compilados se habrán guardado en una carpeta denominada \x64\Debug para una compilación de depuración de 64 bits.
Vaya a la carpeta que contiene los archivos compilados para el controlador Autosync: C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.
La carpeta debe contener estos archivos:
Archivo Descripción Echo.sys El archivo del controlador. Echo.inf Archivo de información (INF) que contiene información necesaria para instalar el controlador. Además, el archivo echoapp.exe se ha compilado y debería encontrarse aquí: C:\DriverSamples\general\echo\kmdf\exe\x64\Debug.
Archivo Descripción EchoApp.exe Un archivo de prueba ejecutable del símbolo del sistema que se comunica con el controlador echo.sys. Busque una unidad USB o configure un recurso compartido de red para copiar los archivos de controlador creados y la EchoApp de prueba desde el sistema host al sistema de destino.
En la sección siguiente, copiará el código en el sistema de destino e instalará y probará el controlador.
Instalación del ejemplo de controlador de eco en el sistema de destino
En esta sección, usará la herramienta DevCon para instalar el controlador de ejemplo de eco.
El equipo en el que se instala el controlador se denomina equipo de destino o equipo de prueba. Normalmente, este equipo es independiente del equipo en el que desarrolla y compila el paquete de controladores. El equipo donde desarrolla y compila el controlador se denomina equipo host.
El proceso de mover el paquete de controladores al equipo de destino e instalar el controlador se denomina implementación del controlador.
Antes de implementar un controlador firmado de prueba, prepare el equipo de destino habilitando la firma de pruebas. También debe buscar la herramienta DevCon en la instalación de WDK y copiarla en el sistema de destino.
Para instalar el controlador en el sistema de destino, siga los pasos siguientes.
En el sistema de destino, habilite controladores firmados de prueba:
Abra Configuración de Windows.
En Actualización y seguridad, seleccione Recuperación.
En Inicio avanzado, seleccione Reiniciar ahora.
Cuando se reinicie el equipo, seleccione Opciones de inicio. En Windows 10, seleccione Solución de problemas>Opciones avanzadas>Configuración de inicio y, a continuación, seleccione Reiniciar.
Seleccione Deshabilitar aplicación de firmas del controlador pulsando la tecla F7.
Reinicie el equipo de destino.
En el sistema host, vaya a la carpeta Herramientas de la instalación de WDK y busque la herramienta DevCon. Por ejemplo, busque en la carpeta siguiente: C:\Archivos de programa (x86)\Windows Kits\10\Tools\x64\devcon.exe.
Cree una carpeta en el destino para el paquete de controladores compilado, por ejemplo, C:\EchoDriver. Copie devcon.exe en el sistema de destino. Busque el certificado .cer en el sistema host. Está en la misma carpeta del equipo host de la carpeta que contiene los archivos de controlador compilado. Copie todos los archivos del controlador compilado descrito anteriormente en el equipo host y guárdelos en la misma carpeta que creó en el equipo de destino.
En el equipo de destino, seleccione y mantenga pulsado (o haga clic con el botón derecho) el archivo de certificado, seleccione Instalar y, a continuación, siga las indicaciones para instalar el certificado de prueba.
Si necesita instrucciones más detalladas para configurar el equipo de destino, consulte Preparación de un equipo para la implementación manual de controladores.
En las instrucciones siguientes se muestra cómo instalar y probar el controlador de ejemplo. Esta es la sintaxis general de la herramienta devcon que se usa para instalar el controlador:
devcon install <INF file> <hardware ID>
El archivo INF necesario para instalar este controlador es echo.inf. El archivo INF contiene el identificador de hardware para instalar echo.sys. Para el ejemplo de eco, el identificador de hardware es root\ECHO.
En el equipo de destino, abra una ventana de símbolo del sistema como administrador. Vaya a la carpeta del paquete de controladores y escriba el siguiente comando:
devcon install echo.inf root\ECHO
Si recibe un mensaje de error sobre devcon que no se reconoce, intente agregar la ruta de acceso a la herramienta devcon. Por ejemplo, si lo copió en una carpeta denominada C:\Tools, pruebe a usar el siguiente comando:
c:\tools\devcon install echo.inf root\ECHO
Aparecerá un cuadro de diálogo que indica que el controlador de prueba es un controlador sin firmar. Seleccione Instalar este controlador de todos modos para continuar.
Sugerencia
Si tiene algún problema con la instalación, consulte el archivo siguiente para obtener más información. %windir%\inf\setupapi.dev.log
Después de instalar correctamente el controlador de ejemplo, ya está listo para probarlo.
En el equipo de destino, en una ventana del símbolo del sistema, escriba devmgmt para abrir Administrador de dispositivos. En Administrador de dispositivos, en el menú Ver, elija Dispositivos por tipo. En el árbol de dispositivos, busque Controlador de eco de WDF de ejemplo en el nodo Dispositivo de ejemplo.
Escriba echoapp para iniciar la aplicación de eco de prueba para confirmar que el controlador es funcional.
C:\Samples\KMDF_Echo_Sample> echoapp
DevicePath: \\?\root#sample#0005#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
Opened device successfully
512 Pattern Bytes Written successfully
512 Pattern Bytes Read successfully
Pattern Verified successfully
30720 Pattern Bytes Written successfully
30720 Pattern Bytes Read successfully
Pattern Verified successfully
Uso de WinDbg para mostrar información sobre el controlador
En esta sección, establecerá la ruta de acceso del símbolo y usará comandos del depurador de kernel para mostrar información sobre el controlador de ejemplo de eco de KMDF.
Para ver información sobre el controlador:
En el sistema host, si cerró el depurador, ábralo de nuevo mediante el siguiente comando en la ventana del símbolo del sistema del administrador.
WinDbg -k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Use Ctrl+Interrumpir (Bloq Despl) para irrumpir en el código que se ejecuta en el sistema de destino.
Para establecer la ruta de acceso de símbolos al servidor de símbolos de Microsoft en el entorno de WinDbg, use el comando
.symfix
.0: kd> .symfix
Para agregar la ubicación del símbolo local para usar los símbolos locales, agregue la ruta de acceso mediante
.sympath+
y, a continuación,.reload /f
.0: kd> .sympath+ C:\DriverSamples\general\echo\kmdf 0: kd> .reload /f
El comando
.reload
con la opción de aplicación/f
elimina toda la información de símbolos del módulo especificado y vuelve a cargar los símbolos. En algunos casos, este comando también recarga o descarga el propio módulo.
Para usar todas las funciones avanzadas que proporciona WinDbg, debe cargar los símbolos adecuados. Si no tiene símbolos configurados correctamente, recibirá mensajes que indican que los símbolos no están disponibles al intentar usar la funcionalidad que depende de los símbolos.
0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.
Hay muchos enfoques que se pueden usar para trabajar con símbolos. En muchas situaciones, puede configurar el equipo para acceder a símbolos desde un servidor de símbolos que Microsoft proporciona cuando son necesarios. En este laboratorio se usa ese enfoque. Si los símbolos del entorno están en una ubicación diferente, modifique los pasos para usar esa ubicación. Para obtener más información, consulte Ruta de símbolos para la depuración de Windows.
Para realizar la depuración de origen, debe crear una versión comprobada (depuración) de los archivos binarios. El compilador crea archivos de símbolos (archivos .pdb). Estos archivos de símbolos muestran al depurador cómo las instrucciones binarias corresponden a las líneas de origen. Los propios archivos de origen también deben ser accesibles para el depurador.
Los archivos de símbolos no contienen el texto del código fuente. Para la depuración, es mejor si el enlazador no optimiza el código. La depuración de origen y el acceso a las variables locales son más difíciles y, a veces, casi imposibles, si el código se ha optimizado. Si tiene problemas para ver variables locales o líneas de origen, establezca las siguientes opciones de compilación:
set COMPILE_DEBUG=1
set ENABLE_OPTIMIZER=0
Escriba el siguiente comando en el área de comandos del depurador para mostrar información sobre el controlador de eco:
0: kd> lm m echo* v Browse full module list start end module name fffff801`4ae80000 fffff801`4ae89000 ECHO (private pdb symbols) C:\Samples\KMDF_ECHO_SAMPLE\echo.pdb Loaded symbol image file: ECHO.sys Image path: \SystemRoot\system32\DRIVERS\ECHO.sys Image name: ECHO.sys ...
Para obtener más información, consulte lm.
Dado que en este laboratorio se estableció
prefer_dml
anteriormente, algunos elementos de la salida son vínculos activos que puede seleccionar. Seleccione el vínculo Examinar todos los símbolos globales de la salida de depuración para mostrar información sobre los símbolos de elementos que comienzan con la letra "a".0: kd> x /D Echo!a*
El ejemplo de eco no contiene ningún símbolo que comience con la letra "a", por lo que escriba
x ECHO!Echo*
para mostrar información sobre todos los símbolos asociados con el controlador de eco que comienzan por "Echo".0: kd> x ECHO!Echo* fffff801`0bf95690 ECHO!EchoEvtIoQueueContextDestroy (void *) fffff801`0bf95000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) fffff801`0bf95ac0 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) fffff801`0bf9b120 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) ...
Para obtener más información, consulte x (Examinar símbolos).
La extensión
!lmi
muestra información detallada sobre un módulo. Escriba!lmi echo
. La salida debe ser similar al texto que se muestra en este ejemplo:0: kd> !lmi echo Loaded Module Info: [echo] Module: ECHO Base Address: fffff8010bf94000 Image Name: ECHO.sys …
Use la extensión
!dh
para mostrar información de encabezado como se muestra en este ejemplo:0: kd> !dh echo File Type: EXECUTABLE IMAGE FILE HEADER VALUES 14C machine (i386) 6 number of sections 54AD8A42 time date stamp Wed Jan 07 11:34:26 2015 ...
Escriba lo siguiente para cambiar la máscara de bits de depuración predeterminada para que todos los mensajes de depuración del sistema de destino se muestren en el depurador:
0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
Algunos controladores muestran información adicional cuando se usa la máscara de 0xFFFFFFFF. Establezca la máscara en 0x00000000 si desea reducir la cantidad de información que se muestra.
0: kd> ed nt!Kd_DEFAULT_MASK 0x00000000
Use el comando
dd
para confirmar que la máscara está establecida para mostrar todos los mensajes del depurador.0: kd> dd nt!kd_DEFAULT_MASK fffff802`bb4057c0 ffffffff 00000000 00000000 00000000 fffff802`bb4057d0 00000000 00000000 00000000 00000000 fffff802`bb4057e0 00000001 00000000 00000000 00000000 fffff802`bb4057f0 00000000 00000000 00000000 00000000 fffff802`bb405800 00000000 00000000 00000000 00000000 fffff802`bb405810 00000000 00000000 00000000 00000000 fffff802`bb405820 00000000 00000000 00000000 00000000 fffff802`bb405830 00000000 00000000 00000000 00000000
Visualización de la información del árbol de dispositivos Plug and Play
En esta sección, visualizará información sobre el controlador de dispositivo de ejemplo de eco y dónde reside en el árbol de dispositivos Plug and Play.
La información sobre el controlador de dispositivo en el árbol de dispositivos Plug and Play puede resultar útil para solucionar problemas. Por ejemplo, si un controlador de dispositivo no reside en el árbol de dispositivos, puede haber un problema con la instalación del controlador de dispositivo.
Para obtener más información sobre la extensión de depuración del nodo de dispositivo, consulte !devnode.
En el sistema host, para ver todos los nodos de dispositivo en el árbol de dispositivos Plug and Play, escriba el comando
!devnode 0 1
.0: kd> !devnode 0 1 Dumping IopRootDeviceNode (= 0xffffe0005a3a8d30) DevNode 0xffffe0005a3a8d30 for PDO 0xffffe0005a3a9e50 InstancePath is "HTREE\ROOT\0" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a3a3d30 for PDO 0xffffe0005a3a4e50 InstancePath is "ROOT\volmgr\0000" ServiceName is "volmgr" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a324560 for PDO 0xffffe0005bd95ca0… …
Use Ctrl+F para buscar en la salida que se genera el nombre del controlador de dispositivo, echo.
Se debería cargar el controlador del dispositivo de eco. Use el comando
!devnode 0 1 echo
para mostrar información de Plug and Play asociada al controlador del dispositivo de eco, como se muestra en este ejemplo:0: Kd> !devnode 0 1 echo Dumping IopRootDeviceNode (= 0xffffe0007b725d30) DevNode 0xffffe0007b71a630 for PDO 0xffffe0007b71a960 InstancePath is "ROOT\SAMPLE\0000" ServiceName is "ECHO" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) …
La salida mostrada en el comando anterior incluye el PDO asociado a la instancia en ejecución del controlador, en este ejemplo, 0xffffe0007b71a960. Escriba el comando
!devobj <PDO address>
para mostrar información de Plug and Play asociada al controlador de dispositivo de eco. Use la dirección PDO que!devnode
muestra en el equipo, no la que se muestra aquí.0: kd> !devobj 0xffffe0007b71a960 Device object (ffffe0007b71a960) is for: 0000000e \Driver\PnpManager DriverObject ffffe0007b727e60 Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001040 Dacl ffffc102c9b36031 DevExt 00000000 DevObjExt ffffe0007b71aab0 DevNode ffffe0007b71a630 ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN AttachedDevice (Upper) ffffe000801fee20 \Driver\ECHO Device queue is not busy.
La salida mostrada en el comando
!devnode 0 1
incluye la dirección PDO asociada a la instancia en ejecución del controlador, en este ejemplo, es 0xffffe0007b71a960. Escriba el comando!devstack <PDO address>
para mostrar información de Plug and Play asociada al controlador de dispositivo. Use la dirección PDO que!devnode
muestra en el equipo, no la que se muestra en este ejemplo.0: kd> !devstack 0xffffe0007b71a960 !DevObj !DrvObj !DevExt ObjectName ffffe000801fee20 \Driver\ECHO ffffe0007f72eff0 > ffffe0007b71a960 \Driver\PnpManager 00000000 0000000e !DevNode ffffe0007b71a630 : DeviceInst is "ROOT\SAMPLE\0000" ServiceName is "ECHO"
La salida muestra que tiene una pila de controladores de dispositivo muy sencilla. El controlador de eco es un elemento secundario del nodo PnPManager. PnPManager es un nodo raíz.
\Driver\ECHO
\Driver\PnpManager
En este diagrama se muestra un árbol de nodos de dispositivo más complejo.
Para obtener más información sobre las pilas de controladores más complejas, consulte Pilas de controladores y Nodos de dispositivo y pilas de dispositivos.
Trabajo con puntos de interrupción y código fuente
En esta sección, establecerá puntos de interrupción y código fuente en modo kernel de un solo paso.
Para poder recorrer el código y comprobar los valores de las variables en tiempo real, habilite los puntos de interrupción y establezca una ruta de acceso al código fuente.
Los puntos de interrupción detienen la ejecución de código en una línea de código determinada. Avance en el código desde ese punto para depurar esa sección específica del código.
Para establecer un punto de interrupción mediante un comando de depuración, use uno de los siguientes comandos b
.
Comando | Descripción |
---|---|
bp |
Establece un punto de interrupción que estará activo hasta que se descargue el módulo en el que se encuentra. |
bu |
Establece un punto de interrupción que no se resuelve cuando el módulo se descarga y se vuelve a habilitar cuando el módulo se vuelve a cargar. |
bm |
Establece un punto de interrupción para un símbolo. Este comando usa bu o bp adecuadamente y permite usar caracteres comodín (* ) para establecer puntos de interrupción en todos los símbolos que coincidan, como todos los métodos de una clase. |
Para obtener más información, consulte Depuración de código fuente en WinDbg.
En el sistema host, use la interfaz de usuario de WinDbg para confirmar que Depuración>Modo de origen está habilitado en la sesión actual de WinDbg.
Escriba el comando siguiente para añadir la ubicación de su código local a la ruta de origen:
.srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Escriba el comando siguiente para añadir la ubicación de símbolo local a la ruta de símbolos:
.sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Use el comando
x
para examinar los símbolos asociados al controlador de eco para determinar el nombre de la función que se va a usar para el punto de interrupción. Puede usar un carácter comodín o Ctrl+F para buscar el nombre de la funciónDeviceAdd
.0: kd> x ECHO!EchoEvt* 8b4c7490 ECHO!EchoEvtIoQueueContextDestroy (void *) 8b4c7000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) 8b4c7820 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) 8b4cb0e0 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) 8b4c75d0 ECHO!EchoEvtIoWrite (struct WDFQUEUE__ *, struct WDFREQUEST__ *, unsigned int) 8b4cb170 ECHO!EchoEvtDeviceAdd (struct WDFDRIVER__ *, struct …
La salida muestra que el método
DeviceAdd
para el controlador de eco esECHO!EchoEvtDeviceAdd
.También puede revisar el código fuente para buscar el nombre de la función para el punto de interrupción.
Establezca el punto de interrupción con el comando
bm
utilizando el nombre del controlador, seguido del nombre de la función, por ejemplo,AddDevice
, donde desea establecer el punto de interrupción, separados por un signo de exclamación. En este laboratorio se usaAddDevice
para ver el controlador que se carga.0: kd> bm ECHO!EchoEvtDeviceAdd 1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
Puede usar una sintaxis diferente junto con la configuración de variables como
<module>!<symbol>
,<class>::<method>
'<file.cpp>:<line number>'
u omitir un número de veces<condition> <#>
. Para obtener más información, consulte Puntos de interrupción condicionales en WinDbg y otros depuradores de Windows.Enumere los puntos de interrupción actuales para confirmar que el punto de interrupción se estableció escribiendo el comando
bl
:0: kd> bl 1 e fffff801`0bf9b1c0 0001 (0001) ECHO!EchoEvtDeviceAdd
La "e" de la salida que se muestra aquí indica que el número de punto de interrupción 1 está habilitado para activarse.
Reinicie la ejecución de código en el sistema de destino escribiendo el comando
g
(ir).En el sistema de destino, en Windows, abra Administrador de dispositivos mediante el icono o escribiendo mmc devmgmt.msc. En Administrador de dispositivos, expanda el nodo Ejemplos.
Seleccione y mantenga pulsada (o haga clic con el botón derecho) la entrada del controlador de eco de KMDF y seleccione Deshabilitar en el menú.
Vuelva a seleccionar y mantenga pulsada (o haga clic con el botón derecho) la entrada del controlador de eco de KMDF y seleccione Habilitar en el menú.
En el sistema host, cuando el controlador está habilitado, el punto de interrupción de depuración AddDevice debería activarse. La ejecución del código de controlador en el sistema de destino debería detenerse. Cuando se alcanza el punto de interrupción, la ejecución debería detener al principio de la rutina AddDevice. La salida del comando de depuración muestra
Breakpoint 1 hit
.Para recorrer la línea de código por línea, escriba el comando
p
o pulse F10 hasta llegar al siguiente final de la rutina AddDevice. El carácter de llave (}
) está resaltado como se muestra.
En la sección siguiente, examine el estado de las variables después de ejecutar el código DeviceAdd.
Puede modificar los puntos de interrupción existentes mediante los siguientes comandos:
Comando | Descripción |
---|---|
bl |
Enumera los puntos de interrupción. |
bc |
Borra un punto de interrupción de la lista. Use bc * para borrar todos los puntos de interrupción. |
bd |
Deshabilita un punto de interrupción. Use bd * para deshabilitar todos los puntos de interrupción. |
be |
Habilita un punto de interrupción. Use be * para habilitar todos los puntos de interrupción. |
También puede modificar puntos de interrupción en la interfaz de usuario de WinDbg.
También puede establecer puntos de interrupción que se activan cuando se accede a una ubicación de memoria. Use el comando ba
(interrumpir el acceso), con la siguiente sintaxis:
ba <access> <size> <address> {options}
Opción | Descripción |
---|---|
e |
ejecutar: cuando la CPU captura una instrucción de la dirección |
r |
leer/escribir: cuando la CPU lee o escribe en la dirección |
w |
escribir: cuando la CPU escribe en la dirección |
Solo puede establecer cuatro puntos de interrupción de datos en un momento dado. Es necesario asegurarse de que está alineando los datos correctamente para desencadenar el punto de interrupción. Las palabras deben terminar en direcciones divisibles en 2, las palabras dwords deben ser divisibles por 4 y las palabras cuádruples por 0 o 8.
Por ejemplo, para establecer un punto de interrupción de lectura/escritura en una dirección de memoria específica, podría usar un comando como el de este ejemplo.
ba r 4 0x0003f7bf0
Pude usar los comandos siguientes para recorrer el código con los métodos abreviados del teclado asociados que se muestran entre paréntesis.
- Interrumpir (Ctrl+Interrumpir). Este comando interrumpe un sistema mientras el sistema se esté ejecutando y esté en comunicación con WinDbg. La secuencia del depurador de kernel es Ctrl+C.
- Ejecutar hasta el cursor (F7 o Ctrl+F10). Coloque el cursor en una ventana de origen o desensamblado donde quiera que se interrumpa la ejecución y pulse F7. La ejecución del código se ejecuta hasta ese punto. Si el flujo de ejecución de código no llega al punto indicado por el cursor, WinDbg no se interrumpirá. Esta situación puede ocurrir si no se ejecuta una instrucción IF.
- Ejecutar (F5). Se ejecuta hasta que se encuentra un punto de interrupción o se produce un evento, como una comprobación de errores.
- Paso a paso por procedimientos (F10). Este comando hace que la ejecución del código continúe con una instrucción o una instrucción a la vez. Si se encuentra una llamada, la ejecución del código pasa por la llamada sin escribir la rutina llamada. Si el lenguaje de programación es C o C++ y WinDbg está en modo de origen, el modo de origen se puede activar o desactivar mediante Depuración>Modo de origen.
- Paso a paso por instrucciones (F11). Este comando es similar al paso a paso por procedimientos, excepto que la ejecución de una llamada entra en la rutina llamada.
- Paso a paso para salir (Mayús+F11). Este comando hace que la ejecución se ejecute y salga de la rutina actual o del lugar actual en la pila de llamadas. Este comando es útil si ha visto suficiente de la rutina.
Para obtener más información, consulte Depuración de código fuente en WinDbg.
Visualización de variables y pilas de llamadas
En esta sección, visualizará información sobre las variables y las pilas de llamadas.
En este laboratorio se supone que se ha detenido en la rutina AddDevice mediante el proceso descrito anteriormente. Para ver la salida que se muestra aquí, repita los pasos descritos anteriormente, si es necesario.
En el sistema host, para mostrar variables, use la opción de menú Ver>Local para mostrar variables locales.
Para buscar la ubicación de una dirección de variables global, escriba ? <variable name>
.
- Paso a paso para salir (Mayús+F11): este comando hace que la ejecución se ejecute y salga de la rutina actual (lugar actual en la pila de llamadas). Esto es útil si ha visto suficiente de la rutina.
Para obtener más información, consulte Depuración de código fuente en WinDbg (clásico) en la documentación de referencia de depuración.
Sección 8: Visualización de variables y pilas de llamadas
En la sección 8, visualizará información sobre las variables y las pilas de llamadas.
En este laboratorio se supone que se ha detenido en la rutina AddDevice mediante el proceso descrito anteriormente. Para ver la salida que se muestra aquí, repita los pasos descritos anteriormente, si es necesario.
<- En el sistema host
Visualización de variables
Use la opción de menú Ver>Local para visualizar variables locales.
Variables globales
Para encontrar la ubicación de una dirección de variable global, escriba ? <nombre de variable>..
Variables locales
Puede mostrar los nombres y valores de todas las variables locales de un marco determinado escribiendo el comando dv.
Para mostrar los nombres y valores de todas las variables locales de un marco específico, escriba el comando dv
:
0: kd> dv
Driver = 0x00001fff`7ff9c838
DeviceInit = 0xffffd001`51978190
status = 0n0
La pila de llamadas es la cadena de llamadas a la función que han llevado a la ubicación actual del contador del programa. La función superior de la pila de llamadas es la función actual y la función siguiente es la función que llamó a la función actual, etc.
Para mostrar la pila de llamadas, use los comandos k*
.
Comando | Descripción |
---|---|
kb |
Muestra la pila y los tres primeros parámetros. |
kp |
Muestra las pilas y la lista completa de parámetros. |
kn |
Permite ver la pila con la información de marco junto a ella. |
En el sistema host, si desea mantener la pila de llamadas disponible, seleccione Ver>Pila de llamadas para verla. Seleccione las columnas de la parte superior de la ventana para alternar la presentación de información adicional.
Use el comando
kn
para mostrar la pila de llamadas mientras depura el código del adaptador de ejemplo en un estado de interrupción.3: kd> kn # Child-SP RetAddr Call Site 00 ffffd001`51978110 fffff801`0942f55b ECHO!EchoEvtDeviceAdd+0x66 [c:\Samples\kmdf echo sample\c++\driver\autosync\driver.c @ 138] 01 (Inline Function) --------`-------- Wdf01000!FxDriverDeviceAdd::Invoke+0x30 [d:\wbrtm\minkernel\wdf\framework\shared\inc\private\common\fxdrivercallbacks.hpp @ 61] 02 ffffd001`51978150 fffff801`eed8097d Wdf01000!FxDriver::AddDevice+0xab [d:\wbrtm\minkernel\wdf\framework\shared\core\km\fxdriverkm.cpp @ 72] 03 ffffd001`51978570 fffff801`ef129423 nt!PpvUtilCallAddDevice+0x35 [d:\9142\minkernel\ntos\io\pnpmgr\verifier.c @ 104] 04 ffffd001`519785b0 fffff801`ef0c4112 nt!PnpCallAddDevice+0x63 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 7397] 05 ffffd001`51978630 fffff801`ef0c344f nt!PipCallDriverAddDevice+0x6e2 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 3390] ...
La pila de llamadas muestra que el kernel (nt) llamó al código Plug and Play (PnP) que llamó al código marco del controlador (WDF) que posteriormente llamó a la función DeviceAdd
del controlador de eco.
Visualización de procesos y subprocesos
En esta sección, visualizará información sobre los procesos y subprocesos que se ejecutan en modo kernel.
Procesos
Puede mostrar o establecer información del proceso mediante la extensión del depurador !process. Establezca un punto de interrupción para examinar el proceso que se usa cuando se reproduce un sonido.
En el sistema host, escriba el comando
dv
para examinar las variables de configuración regional asociadas a la rutinaEchoEvtIo
:0: kd> dv ECHO!EchoEvtIo* ECHO!EchoEvtIoQueueContextDestroy ECHO!EchoEvtIoWrite ECHO!EchoEvtIoRead
Borre los puntos de interrupción anteriores mediante
bc *
:0: kd> bc *
Establezca un punto de interrupción de símbolos en las rutinas
EchoEvtIo
mediante el comando siguiente:0: kd> bm ECHO!EchoEvtIo* 2: aade5490 @!”ECHO!EchoEvtIoQueueContextDestroy” 3: aade55d0 @!”ECHO!EchoEvtIoWrite” 4: aade54c0 @!”ECHO!EchoEvtIoRead”
Enumere los puntos de interrupción para confirmar que el punto de interrupción está establecido correctamente:
0: kd> bl 1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197] 0001 (0001) ECHO!EchoEvtIoQueueContextDestroy ...
Escriba
g
para reiniciar la ejecución del código:0: kd> g
En el sistema de destino, ejecute el programa de prueba de controladores
EchoApp.exe
en el sistema de destino.En el sistema host, cuando se ejecuta la aplicación de prueba, se llama a la rutina de E/S en el controlador. Esta llamada hace que se active el punto de interrupción y se detenga la ejecución del código del controlador en el sistema de destino.
Breakpoint 2 hit ECHO!EchoEvtIoWrite: fffff801`0bf95810 4c89442418 mov qword ptr [rsp+18h],r8
Use el comando
!process
para mostrar el proceso actual implicado en la ejecución de echoapp.exe:0: kd> !process PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 03c4 Peb: 7ff7cfec4000 ParentCid: 0f34 DirBase: 1efd1b000 ObjectTable: ffffc001d77978c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000802c79f0 Vads 30 Clone 0 Private 135. Modified 5. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf270050 ElapsedTime 00:00:00.052 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (682, 50, 345) (2728KB, 200KB, 1380KB) PeakWorkingSetSize 652 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 688 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe00080e32080 Cid 03c4.0ec0 Teb: 00007ff7cfece000 Win32Thread: 0000000000000000 RUNNING on processor 1
La salida muestra que el proceso está asociado al subproceso de echoapp.exe, que se estaba ejecutando cuando se alcanzó el punto de interrupción en el evento de escritura del controlador. Para obtener más información, consulte !process.
Use
!process 0 0
para visualizar información de resumen para todos los procesos. En la salida, use Ctrl+F para buscar la misma dirección de proceso para el proceso asociado a la imagen de echoapp.exe. En el ejemplo, la dirección del proceso esffffe0007e6a7780
.... PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34 DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34. Image: echoapp.exe ...
Registre el identificador de proceso asociado a echoapp.exe para usarlo más adelante en este laboratorio. También puede usar Ctrl+C para copiar la dirección en el búfer de copia para su uso posterior.
_____________________________________________________(dirección de proceso de echoapp.exe)
Escriba
g
como sea necesario en el depurador para ejecutar el código hasta que echoapp.exe termine de ejecutarse. Alcanza el punto de interrupción en el evento de lectura y escritura muchas veces. Cuando finalice echoapp.exe, interrumpa en el depurador pulsando Ctrl+Bloq Despl (Ctrl+Interrumpir).Use el comando
!process
para confirmar que está ejecutando un proceso diferente. En la salida que se muestra aquí, el proceso con el valor de Imagen de System es diferente del valor de Imagen de Echo.1: kd> !process PROCESS ffffe0007b65d900 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001ab000 ObjectTable: ffffc001c9a03000 HandleCount: 786. Image: System VadRoot ffffe0007ce45930 Vads 14 Clone 0 Private 22. Modified 131605. Locked 64. DeviceMap ffffc001c9a0c220 Token ffffc001c9a05530 ElapsedTime 21:31:02.516 ...
La salida muestra que se estaba ejecutando un proceso del sistema ffffe0007b65d900 cuando se detuvo el sistema operativo.
Use el comando
!process
para intentar examinar el identificador de proceso asociado a echoapp.exe que registró anteriormente. Proporcione la dirección del proceso de echoapp.exe que registró anteriormente, en lugar de la dirección del proceso de ejemplo que se muestra en este ejemplo.0: kd> !process ffffe0007e6a7780 TYPE mismatch for process object at 82a9acc0
El objeto de proceso ya no está disponible porque el proceso de echoapp.exe ya no se está ejecutando.
Subprocesos
Los comandos para ver y establecer subprocesos son similares a los comandos para los procesos. Use el comando !thread para ver los subprocesos. Use .thread para establecer los subprocesos actuales.
En el sistema host, escriba
g
en el depurador para reiniciar la ejecución de código en el sistema de destino.En el sistema de destino, ejecute el programa de prueba de controladores EchoApp.exe.
En el sistema host, se alcanza el punto de interrupción y se detiene la ejecución del código.
Breakpoint 4 hit ECHO!EchoEvtIoRead: aade54c0 55 push ebp
Para ver los subprocesos que se están ejecutando, escriba !thread. Debe mostrarse información similar a la del siguiente ejemplo:
0: kd> !thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe ...
Anote el nombre de la imagen de echoapp.exe. Esto indica que está viendo el subproceso asociado a la aplicación de prueba.
Use el comando
!process
para determinar si este subproceso es el único subproceso que se ejecuta en el proceso asociado a echoapp.exe. El número de subproceso del subproceso en ejecución en el proceso es el mismo subproceso en ejecución que mostró el comando!thread
.0: kd> !process PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
Use el comando
!process 0 0
para buscar la dirección del proceso de dos procesos relacionados y registre esa dirección de proceso aquí.Cmd.exe: ____________________________________________________________
EchoApp.exe: _______________________________________________________
0: kd> !process 0 0 … PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe … PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe …
También puede usar
!process 0 17
para mostrar información detallada sobre cada proceso. La salida de este comando puede ser larga. Se pueden realizar búsquedas en la salida con Ctrl+F.Use el comando
!process
para enumerar la información del proceso para ambos procesos que ejecutan el equipo. Proporcione la dirección del proceso de la salida!process 0 0
, no la dirección que se muestra en este ejemplo.Esta salida de ejemplo es para el identificador de proceso de cmd.exe que se registró anteriormente. El nombre de la imagen de este identificador de proceso es cmd.exe.
0: kd> !process ffffe0007bbde900 PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe VadRoot ffffe0007bb8e7b0 Vads 25 Clone 0 Private 117. Modified 20. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001d8c48050 ElapsedTime 21:33:05.840 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 24656 QuotaPoolUsage[NonPagedPool] 3184 Working Set Sizes (now,min,max) (261, 50, 345) (1044KB, 200KB, 1380KB) PeakWorkingSetSize 616 VirtualSize 2097164 Mb PeakVirtualSize 2097165 Mb PageFaultCount 823 MemoryPriority FOREGROUND BasePriority 8 CommitCharge 381 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating ...
Esta salida de ejemplo es para el identificador de proceso de echoapp.exe que se registró anteriormente.
0: kd> !process ffffe0008096c900 PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating ...
Registre aquí la primera dirección del subproceso asociada a los dos procesos.
Cmd.exe: ____________________________________________________
EchoApp.exe: _________________________________________________
Use el comando
!Thread
para mostrar información sobre el subproceso actual.0: kd> !Thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe Attached Process N/A Image: N/A ...
Como se esperaba, el subproceso actual es el subproceso asociado a echoapp.exe y está en estado de ejecución.
Use el comando
!Thread
para mostrar información sobre el subproceso asociado al proceso cmd.exe. Proporcione la dirección del subproceso que registró anteriormente.0: kd> !Thread ffffe0007cf34880 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0007bbde900 Image: cmd.exe Attached Process N/A Image: N/A Wait Start TickCount 4134621 Ticks: 0 Context Switch Count 4056 IdealProcessor: 0 UserTime 00:00:00.000 KernelTime 00:00:01.421 Win32 Start Address 0x00007ff72e9d6e20 Stack Init ffffd0015551dc90 Current ffffd0015551d760 Base ffffd0015551e000 Limit ffffd00155518000 Call 0 Priority 14 BasePriority 8 UnusualBoost 3 ForegroundBoost 2 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to Child : Call Site ffffd001`5551d7a0 fffff801`eed184fe : fffff801`eef81180 ffffe000`7cf34880 00000000`fffffffe 00000000`fffffffe : nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] ffffd001`5551d8e0 fffff801`eed17f79 : ffff03a5`ca56a3c8 000000de`b6a6e990 000000de`b6a6e990 00007ff7`d00df000 : nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] ffffd001`5551d980 fffff801`eecea340 : ffffd001`5551da18 00000000`00000000 00000000`00000000 00000000`00000388 : nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] ...
Este subproceso está asociado a cmd.exe y está en estado de espera.
Proporcione la dirección del subproceso en espera CMD.exe para cambiar el contexto a ese subproceso en espera.
0: kd> .Thread ffffe0007cf34880 Implicit thread is now ffffe000`7cf34880
Use el comando
k
para ver la pila de llamadas asociada al subproceso en espera.0: kd> k *** Stack trace for last set context - .thread/.cxr resets it # Child-SP RetAddr Call Site 00 ffffd001`5551d7a0 fffff801`eed184fe nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] 01 ffffd001`5551d8e0 fffff801`eed17f79 nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] 02 ffffd001`5551d980 fffff801`eecea340 nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] 03 ffffd001`5551da00 fffff801`ef02e642 nt!KeWaitForSingleObject+0x2c0 [d:\9142\minkernel\ntos\ke\wait.c @ 683] ...
Los elementos de la pila de llamadas como
KiCommitThreadWait
indican que este subproceso no se está ejecutando como se esperaba.
Para obtener más información sobre los procesos y subprocesos, consulte las referencias siguientes:
IRQL, registros y finalización de la sesión de WinDbg
En esta sección, visualizará el nivel de solicitud de interrupción (IRQL) y el contenido de los registros.
Visualización del IRQL guardado
IRQL se usa para administrar la prioridad del mantenimiento de interrupciones. Cada procesador tiene una configuración de IRQL que los subprocesos pueden aumentar o reducir. Las interrupciones que se producen en la configuración IRQL del procesador o por debajo de esta se enmascaran y no interferirán con la operación actual. Las interrupciones que se producen por encima de la configuración de IRQL del procesador tienen prioridad sobre la operación actual.
En el sistema host, la extensión !irql muestra el IRQL en el procesador actual del equipo de destino antes de la interrupción del depurador. Cuando el equipo de destino irrumpe en el depurador, el IRQL cambia, pero se guarda el IRQL que estaba vigente justo antes de la irrupción del depurador y se muestra mediante !irql
.
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
Visualización de los registros
En el sistema host, visualice el contenido de los registros del subproceso actual en el procesador actual mediante el comando r (Registros).
0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
r8=000000000000003e r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc int 3
Como alternativa, puede mostrar el contenido de los registros seleccionando Ver>Registros. Para obtener más información, consulte r (Registros).
La visualización del contenido de los registros puede resultar útil al recorrer paso a paso la ejecución del código del lenguaje de ensamblado y en otros escenarios. Para obtener más información sobre el desensamblado del lenguaje de ensamblado, consulte Desensamblado anotado x86 y Desensamblado anotado x64.
Para obtener información sobre el contenido del registro, consulte Arquitectura x86 y Arquitectura x64.
Finalización de la sesión de WinDbg
Si desea salir del depurador conectado, pero quiere trabajar en el destino, borre los puntos de interrupción mediante bc *
, de modo que el equipo de destino no intente conectarse al depurador del equipo host. A continuación, use el comando g
para permitir que el equipo de destino vuelva a ejecutarse.
Para finalizar la sesión de depuración, en el sistema host, interrumpa en el depurador y escriba el comando qd
(Salir y desasociar) o seleccione Detener depuración en el menú.
0: kd> qd
Para obtener más información, consulte Finalización de una sesión de depuración en WinDbg.
Recursos de depuración de Windows
Hay más información disponible sobre la depuración de Windows. Algunas de estas referencias utilizan versiones anteriores de Windows, como Windows Vista, en sus ejemplos, pero los conceptos tratados son aplicables a la mayoría de las versiones de Windows.
Libros
- Advanced Windows Debugging de Mario Hewardt y Daniel Pravat
- Inside Windows Debugging: A Practical Guide to Debugging and Tracing Strategies in Windows® de Tarik Soulami
- Windows Internals de Pavel Yosifovich, Alex Ionescu, Mark Russinovich y David Solomon
Vídeo
Proveedores de formación