BSOD - Pantalla azul - Analizar el error

Uno de los peores errores en los que nos podemos encontrar es una pantalla azul (BSOD: Blue Screen of Death), congelaciones de la pantalla -cursor y teclado no responden- o reinicios espontáneos.

Empecemos desde el más sencillo:

1) Reinicios espontáneos: en Windows XP, estos reinicios espontáneos suelen ser producidos por tener marcado "Reiniciar Automáticamente" (es la opción por defecto). Dicha opción se modifica con botón derecho sobre Mi PC, propiedades, pestaña de avanzado y botón de inicio y recuperación.

Un reinicio espontáneo es, o bien porque iba a salir una pantalla azul, y al estar seleccionada la opción anterior, en vez de salir, el sistema se reinicia, o bien por un error hardware que el sistema operativo no ha podido atrapar. Si es la primera opción, simplemente debemos configurar para que NO se reinicie automáticamente y dejar que el sistema atrape el error. Si a pesar de eso, siguen los reinicios, implica entonces un error hardware y grave: normalmente placa madre o CPU y poco más podemos diagnosticar en este caso.

2) Pantalla azul: en este caso, nos dará en pantalla un mini-informe del error. Únicamente debemos fijarnos si en dicho mensaje aparece un .sys causante del error. Si *no* aparece este .sys, o lo que aparece son componentes de Windows (ntoskrln, win32k.sys, esbstor.sys, usbyhci.sys), deberemos analizar el archivo DMP que se produce (lo veremos posteriormente).
Si el driver que aparece es un archivo de terceros: ya tenemos localizado al culpable. La solución será actualizar dichos drivers, o dicho componente (los antivirus, si no ha existido cambio de hardware, suelen ser los primeros candidatos).

Un elevado número de veces no sale ningún .sys o .dll causante del error. En ese caso, no nos queda más remedio también que analizar el archivo DMP.

Por desgracia, la utilidad DUMPCHK que viene en las Support Tools de windows XP / W2003 poco nos sirve para analizar el error ya que únicamente nos mostrará lo mismo que nos muestra Windows en la pantalla azul. Por tanto, si Windows al generar la pantalla azul no ha sido capaz de mostrarlo, este herramienta no nos servirá de nada. Más adelante veremos qué herramienta debemos utilizar para ello.

3) Congelaciones de la pantalla. Es un caso similar al 2). Tendremos que analizar el DMP. Ahora bien, ¿cómo podemos en este caso hacer que el sistema nos genere un DMP si el sistema está congelado?

(NO VÁLIDO PARA TECLADOS USB/BLUETOOTH): Para ello, previamente debemos tener configurado el registro para que una combinación de teclas nos provoque el DUMP aunque todo esté congelado. Por tanto, y es mi consejo que por defecto lo tengamos configurado, debemos tener una variable en la clave:

HKEY_LOCAL_MACHINE
System
CurrentControlSet
Services
i8042prt
Parameters

Nombre: CrashOnCtrlScroll
Tipo: DWORD (doble palabra)
Contenido: 1

(y reiniciar la máquina para que esté activo). Con esto, en cualquier momento, e incluso en caso de congelación de la pantalla, podremos provocar el DMP, pulsando la tecla CTRL (derecha) y dos veces consecutivas la tecla SCROLL BLOCK (bloqueo de desplazamiento).

TIPOS DE VOLCADO DE MEMORIA

Existen tres tipos de volcado de memoria, los cuales están activados desde: botón derecho sobre Mi PC, propiedades, pestaña de avanzado y botón de inicio y recuperación:

1) Minidump (64 KB). Realmente vale para poco y no es la mejor opción Si la tenemos activada, nos generará un "minidump" en \windows\minidump

2) Kernel.dmp: opción intermedia: solo se vuelca el kernel (núcleo) y en la mayoría de los casos es suficiente para diagnosticar el error. Genera el archivo MEMORY.DMP en la carpeta Windows.

3) Completo. Para que el DMP completo funcione y no salga "corrupto", es obligatorio tener el archivo de paginación en la misma partición en la cual tenemos Windows. Generará igualmente en ella el archivo MEMORY.DMP

Muchas veces por motivos de rendimiento movemos el archivo de paginación a otro disco físico. Si tenemos BSOD del sistema y deseamos un volcado de memoria completo, deberemos previamente volver a establecer el archivo de paginación en la unidad de Windows. Igualmente debemos recordar que en este caso, debemos tener espacio en disco igual a la memoria física de la máquina ya que ese será el tamaño del archivo DMP creado.

SOFTWARE NECESARIO PARA EL ANALISIS DEL ERROR

La información podemos localizarla en esta página:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009

El software puede instalarse tanto en la propia máquina como en una máquina ajena. No es necesario analizar el archivo .DMP en la misma máquina en la cual ha sucedido el error, pudiendo hacerse en cualquier otra.

PRIMERA CONFIGURACIÓN DEL SOFTWARE

Aunque no es necesario, para poco nos vale un error si no tenemos instalados los ficheros de símbolos. Los símbolos de drivers de terceros no podremos instalarlos porque los fabricantes normalmente no los dan, pero los símbolos de Windows sí que podremos. No aconsejo instalarlo desde el CD, ni descargarse del sitio de Microsoft los símbolos ya que la propia herramienta instalada: WINDBG, una vez configurada, si no tiene los símbolos los descargará en ese momento, y descargará justo los necesarios para ese análisis teniendo en cuenta por tanto los Service Packs y parches que tiene instalados el sistema que estamos analizando.

Para configurarlos de esa manera arrancamos el programa de análisis que hemos instalado: WINDBG y en el menú "File", "Symbol File Path" colocamos:

SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

(en este caso he seleccionado que los símbolos, cuando los descargue, -por ello la primera vez de análisis será lenta, dependiendo de la velocidad de nuestra conexión a Internet- los sitúe en la carpeta: c:\websimbols)

Dicha carpeta puede ser cualquier otra, y lo único que tener presente es que debemos tenerla creada previamente.

VOLCADO DE MEMORIA (DMP o DUMP). ANALISIS DE LOS ARCHIVOS

Un vez configurado tal y como está descrito anteriormente, procedemos a abrir el DUMP con windbg, en el menú "File" y la opción "Open Crash Dump". Podemos abrir cualquier archivo de dump, estemos o no en la máquina que ha causado el casque. Incluso puede abrirse en remoto por ADSL, por ejemplo y aunque el DUMP será de muchas megas, normalmente con sólo leer la cabecera y poco más, estará en disposición de ver datos. En este caso vamos a abrir el DUMP desde otra máquina por red.

NOTA 1: la primera vez que analizamos un dump de un determinado sistema operativo (o con parches específicos), se bajará automáticamente del sitio de Microsoft los ficheros de símbolos necesarios. Por ello, debemos estar conectados a Internet y puede que esa primera vez tarde unos minutos en bajárselos.

Este es un "casque" real en un W2003 Server que está actuando como Controlador de Dominio. Estaba seleccionada la opción de "kernel dump". En la pantalla azul únicamente informó de MULTIPLE_IRP_COMPLETE_REQUESTS, sin dar mas información sobre el módulo causante del fallo.

Lo primero que debemos fijarnos en un DUMP es si en las líneas de cabecera cabecera nos indica si está "corrupto". Si lo estuviese, no nos vale para nada.

NOTA 2: Un dump puede estar corrupto, si tenemos la opción de DUMP completo de memoria y el fichero de paginación reside en otra unidad física. En ese caso, deberemos esperar a repetir el error una vez hayamos puesto el fichero de paginación en la misma unidad que Windows.

Resultado del analizador: (es conveniente leer todos, ya que nos va indicando versión del sistema operativo, parches instalados, etc...) Y sobre todo la parte final:

==============================================================================================

Microsoft (R) Windows Debugger Versión 6.4.0007.2
Copyright (c) Microsoft Corporation. All rights reserved.

Loading Dump File [\\ka000SRV\d$\WINDOWS\MEMORY.DMP]
Kernel Summary Dump File: Only kernel address space is available

Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows Server 2003 Kernel Versión 3790 (Service Pack 1) MP (4 procs) Free x86 compatible
Product: LanManNt, suite: TerminalServer SingleUserTS
Built by: 3790.srv03_sp1_rtm.050324-1447
Kernel base = 0x80800000 PsLoadedModuleList = 0x808af988
Debug session time: Thu May 19 19:32:53.800 2005 (GMT+2)
System Uptime: 0 days 0:05:14.483
Loading Kernel Symbols
.....................................................................
Loading unloaded module list
.
Loading User Symbols
PEB is paged out (Peb.Ldr = 7ffd800c). Type ".hh dbgerr001" for details
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck 44, {87e5a490, d75, 0, 0}

*** ERROR: Module load completed but symbols could not be loaded for ax88172.sys
*** ERROR: Module load completed but symbols could not be loaded for portmap.sys
*** ERROR: Module load completed but symbols could not be loaded for PfModNT.sys
*** ERROR: Module load completed but symbols could not be loaded for nfsrdr.sys
*** ERROR: Module load completed but symbols could not be loaded for dump_Fasttrak.sys
*** ERROR: Module load completed but symbols could not be loaded for winacusb.sys
*** ERROR: Module load completed but symbols could not be loaded for vmm.sys
*** ERROR: Module load completed but symbols could not be loaded for ctac32k.sys
*** ERROR: Module load completed but symbols could not be loaded for ctsfm2k.sys
*** ERROR: Module load completed but symbols could not be loaded for emupia2k.sys
*** ERROR: Module load completed but symbols could not be loaded for ha10kx2k.sys
*** ERROR: Module load completed but symbols could not be loaded for hap16v2k.sys
*** ERROR: Module load completed but symbols could not be loaded for ctoss2k.sys
*** ERROR: Symbol file could not be found. Defaulted to export symbols for drmk.sys -
*** ERROR: Module load completed but symbols could not be loaded for ctaud2k.sys
*** ERROR: Module load completed but symbols could not be loaded for e100b325.sys
*** ERROR: Module load completed but symbols could not be loaded for lstone2k.sys
*** ERROR: Module load completed but symbols could not be loaded for el90xbc5.sys
*** ERROR: Module load completed but symbols could not be loaded for MTXPARHM.sys
*** ERROR: Module load completed but symbols could not be loaded for pfc.sys
*** ERROR: Module load completed but symbols could not be loaded for drmkaud.sys
*** ERROR: Module load completed but symbols could not be loaded for ASAPIW2k.sys
*** ERROR: Module load completed but symbols could not be loaded for MTXPARHD.dll
*** ERROR: Module load completed but symbols could not be loaded for netmate2.sys
*** ERROR: Symbol file could not be found. Defaulted to export symbols for rpcxdr.sys -
*** ERROR: Module load completed but symbols could not be loaded for Fasttrak.sys
*** ERROR: Module load completed but symbols could not be loaded for VMNetSrv.sys
*** ERROR: Module load completed but symbols could not be loaded for TSKNF601.SYS
*** ERROR: Module load completed but symbols could not be loaded for ctprxy2k.sys
*** ERROR: Module load completed but symbols could not be loaded for PSXDRV.SYS
*** ERROR: Module load completed but symbols could not be loaded for memalloc.sys
*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: ocaData ***
*** ***
*************************************************************************
Probably caused by : usbehci.sys

Followup: MachineOwner
---------

==============================================================================

Bien, esta es la primera información del error. Aparece un nombre de módulo candidato: usbehci.sys el cual corresponde a uno de los drivers del propio Windows para USB. Al menos ya sabemos que el casque está provocado por "algo" que está en el bus USB.
Es extraño, a no ser un error hardware, que un driver del propio Microsoft sea el causante.

Fijémonos en que, en una línea superior, la propia salida del debugger nos aconseja:

**** Use !analyze -v to get detailed debugging information.

Por tanto en la línea inferior de la pantalla, procedemos a ejecutar ese comando:

===============================================================================

0: kd> !analyze -v

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

MULTIPLE_IRP_COMPLETE_REQUESTS (44)
A driver has requested that an IRP be completed (IoCompleteRequest()), but
the packet has already been completed. This is a tough bug to find because
the easiest case, a driver actually attempted to complete its own packet
twice, is generally not what happened. Rather, two separate drivers each
believe that they own the packet, and each attempts to complete it. The
first actually works, and the second fails. Tracking down which drivers
in the system actually did this is difficult, generally because the trails
of the first driver have been covered by the second. However, the driver
stack for the current request can be found by examining the DeviceObject
fields in each of the stack locations.
Arguments:
Arg1: 87e5a490, Address of the IRP
Arg2: 00000d75
Arg3: 00000000
Arg4: 00000000

Debugging Details:
------------------

IRP_ADDRESS: 87e5a490

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x44

CURRENT_IRQL: 2

DEVICE_OBJECT: 8a055618

DRIVER_OBJECT: 8a14eaa8

IMAGE_NAME: usbehci.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 42435bb3

MODULE_NAME: usbehci

FAULTING_MODULE: ba27b000 usbehci

LAST_CONTROL_TRANSFER: from 808596ec to 8087b6be

STACK_TEXT:
f789ee10 808596ec 00000044 87e5a490 00000d75 nt!KeBugCheckEx+0x1b
f789ee48 ba11ddc4 87e5a490 88770eb0 8a0e1028 nt!IopfCompleteRequest+0x2f7
f789eeb0 ba11ea45 b70989c0 00000000 8083b28b USBPORT!USBPORT_CompleteTransfer+0x38c
f789eee0 ba11f558 026e6f44 8a0e10e0 8a0e10e0 USBPORT!USBPORT_DoneTransfer+0x137
f789ef18 ba120d58 8a0e1028 8083b28b 8a0e1230 USBPORT!USBPORT_FlushDoneTransferList+0x168
f789ef44 ba12eef2 8a0e1028 8083b28b 8a0e1028 USBPORT!USBPORT_DpcWorker+0x224
f789ef80 ba12f06a 8a0e1028 00000001 ffdffa40 USBPORT!USBPORT_IsrDpcWorker+0x380
f789ef9c 8083eb0f 8a0e164c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166
f789eff4 8083a92b b76d5d44 00000000 00000000 nt!KiRetireDpcList+0xca

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_NAME: MachineOwner

FAILURE_BUCKET_ID: 0x44_IMAGE_usbehci.sys_DATE_3_25_2005

BUCKET_ID: 0x44_IMAGE_usbehci.sys_DATE_3_25_2005

Followup: MachineOwner
---------

===================================================================

La salida del comando nos da la explicación de por qué ocurre un MULTIPLE_IRP_COMPLETE_REQUESTS, básicamente nos informa de que un driver ha solicitado la ejecución de un IRP (IoCompleteRequest) pero el paquete ya había sido completado. Nos dice que es un problema no resuelto por el software y difícil de encontrar, ya que en el mejor de los casos, un driver erróneo que pidió su propio paquete dos veces, no suele ser lo que ha sucedido. Nos dice igualmente que lo más probable es que haya dos drivers diferentes, cada uno de ellos cree que el paquete es suyo y hacen intentos para completarlo. Por último indica que seguir la pista de esto no suele ser fácil.

Veamos que se equivoca, y que al menos en nuestro caso es sencillo de seguir ;-)

Si no fijamos igualmente en la parte anterior, nos da la dirección del IRP en estas líneas:

Arguments:
Arg1: 87e5a490, Address of the IRP
Arg2: 00000d75
Arg3: 00000000
Arg4: 00000000

Por tanto, vamos a pedir al debugguer que nos muestre el contenido de esa dirección ejecutando el comando: !IRP con la dirección anterior:

====================================================================

0: kd> !IRP 87e5a490
Irp is active with 3 stacks 3 is current (= 0x87e5a548)
No Mdl Thread 00000000: Irp stack trace.
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
> [ f, 0] 0 c0 8a055618 00000000 b69de300-00000000 Success Error
\Driver\usbehci ax88172
Args: b70989c0 00000000 00220003 00000000

====================================================================

Esta última línea nos da todos los drivers que han intervenido "creyendo" que un paquete era suyo y han intentado completar la petición. Y al no ser realmente suya es lo que ha provocado el fallo del sistema. Vemos en la penúltima línea que son:

\Driver\usbehci ax88172

El primero corresponde al stack USB de Windows... y el segundo a un "dudoso" y no certificado driver de un dispositivo de red (una NIC LAN 10/100). El aix88712 es el chip que monta y su driver se llama igual.

Por tanto... ya sabemos quien ha sido el culpable :-)