¿Cuánto hace que no miras los disipadores de calor por si han acumulado polvo?

Ha transcurrido un mes y medio desde mi último post, ya me vale.

Hace unos días, en el blog de solución de problemas y depuración avanzada de Windows*, un ingeniero de soporte de Microsoft expuso un curioso problema en casa con uno de sus ordenadores. Estaba un día escaneando unas fotografías y de pronto le salió una pantalla azul. En un primer momento pensó que fue casual: según él, la máquina había funcionado bien hasta entonces. Sin embargo, el problema se repetía nuevamente al volver a escanear fotos, así que decidió investigarlo.

La primera impresión es sospechar de alguno de los componentes involucrados en la tarea que se estaba realizando cuando falló el sistema. En este caso, el controlador del escáner o el del USB —se supone que este escáner se comunica con el PC a través de un puerto USB— serían los candidatos con más papeletas. Sin embargo, el amigo Chad aseguró que estuvo usando el escáner durante mucho tiempo con los mismos controladores software sin observar inconveniente alguno. Esas caídas repentinas del sistema resultaban misteriosas.

Me limitaré a comentar brevemente el análisis del volcado de memoria. Podéis ver los detalles en el post de Chad: Debugging a bluescreen at home. En inglés, claro.

Todo análisis que se precie debe empezar introduciendo la orden !analyze -v en WinDbg. Esto proporciona información básica acerca de las condiciones del error, como el código de STOP, sus cuatro parámetros, el contenido de los registros y la secuencia de llamadas a subrutinas.

El volcado de pila parecía normal hasta cierto punto: una DLL del software del escáner llamó a una rutina de User32.dll que, eventualmente, acabaría en Win32k.sys, la implementación del sistema gráfico de Windows en modo kernel. La rutina ValidateHwnd de Win32k.sys llamó a una supuesta función en la dirección virtual 0x8738e300, donde se intentó acceder a memoria a través de un puntero no válido. Esto es un error grave.

Es extraño que el depurador no fuera capaz de hacer corresponder la dirección 0x8738e300 a ningún módulo ejecutable. Era tierra de nadie. Un pequeño vistazo a los valores de memoria en torno a esa dirección revelaba una zona de datos en pleno pool no paginado. La causa inmediata del fallo fue consecuencia de un intento de ejecución de datos como código. Se da la circunstancia de que el patrón 00 00 hexadecimal corresponde a una instrucción válida en el conjunto de instrucciones x86 de 32 bits: ADD [EAX], AL (sumar el valor del registro AL al byte de la dirección de memoria a la que apunta el registro EAX).

Uno puede pensar en este momento en un puntero sin control, un puntero que apunta a una posición arbitraria de memoria. El desensamblado de las instrucciones previas a la dirección de retorno en Win32k!ValidateHwnd sugiere que la intención era llamar a la función nt!PsGetCurrentThread a través de un puntero global situado en una dirección fija. Ese puntero apuntaba a la dirección correcta.

Entonces, ¿que pudo hacer saltar al microprocesador a una dirección de memoria totalmente equivocada? La apertura de la carcasa del PC descubrió una realidad inquietante. La fotografía del conjunto disipador-ventilador del microprocesador habla por sí sola. Cuando Chad sacó de ahí toda esa suciedad, el ordenador volvió a funcionar con normalidad.

Conclusión: el proceso de escanear fotos debía de poner el procesador a trabajar a pleno rendimiento, con la consiguiente disipación de energía en forma de calor. El sistema de enfriamiento estaría desbordado, con un disipador ineficaz y un ventilador incapaz de llevar a cabo su tarea por muy rápido que girase.

Llegado a este punto, tengo algunas dudas:

  • Cuando el microprocesador se calienta, el ventilador suele acelerarse. Quizá el ventilador de la máquina de Chad no estaba controlado automáticamente o ya giraba a su velocidad máxima. Y justamente un ventilador a máxima velocidad acostumbra a hacer mucho ruido. (Uno también puede acostumbrarse al ruido, claro.)
  • Lo habitual es que la circuitería de la placa base desconecte momentáneamente y reinicialice el procesador en caso de sobrecalentamiento. Esto se observaría como un reinicio espontáneo de la máquina.
  • ¿Cómo es posible que el microprocesador, después de haber cargado en su puntero de instrucción (registro EIP) una dirección errónea, continuara funcionando como si nada hubiese ocurrido? En mi opinión, el sistema debería haber fallado de manera más espectacular, sin pantalla azul y mucho menos con un volcado de memoria completo y consistente.

En fin, bien está lo que bien acaba. O como dirían los anglosajones: All’s well that ends well.

* Si alguien tiene idea de una traducción más precisa de Microsoft Advanced Windows Debugging and Troubleshooting, por favor, que la comparta.