miércoles, 11 de noviembre de 2015

X-Files y Poltergeists. Cuando Windows está maldito

Hace poco me encontraba con uno de esos problemas de resolución aparentemente imposible en una máquina Windows Server 2008 de 64 bits.

En ocasiones, la información y soporte que Microsoft dan al respecto son tremendamente pobres y a veces incluso dicha información es confusa o inexacta.

Tal fue el asunto que me tuvo ocupado con la susodicha máquina hasta casi el borde de la desesperación. Sin pistas, sin ningún otro caso descrito similar en ningún foro, la cosa pintaba mal. Sería el típico caso en que la mayoría de administradores de sistemas habrían optado por reinstalar todo el sistema operativo. Pero en mi caso, eso no era una opción.

De hecho, nunca me ha parecido una opción. Reiniciar o reinstalar vendría a suponer, en la analogía de un médico, amputar una pierna porque no se esforzó lo suficiente en encontrar la causa que le provoca el dolor al paciente.

Así que vamos allá. La solución fue usar la fuerza bruta en un modo en el que se pueden solucionar otras muchas complicaciones en Windows. 


 Los síntomas


Todo comenzó cuando el cliente se quejó de que parte de la aplicación web que corre en ese servidor se quedaba congelada. Pero ocurría sólo con determinadas funcionalidades, no con todo el website. La primera reacción del desarrollador de la aplicación fue descargar de la nube un backup para reinstalar todos los fuentes de la aplicación y ver si eso lo solucionaba.

Y así llegó el segundo susto: no conseguía descargar nada en Google Chrome. El Internet Explorer, directamente no se abría, arrojando un fabuloso error 0xc0000005 (que no es otra cosa que un Acceso denegado de toda la vida); el propio Windows bloqueaba la descarga por "razones de seguridad". Obviamente la reacción lógica fue ir al panel de control y buscar el icono de Internet Settings para comprobar si el nivel de seguridad estaba demasiado alto. Pero... ¡oh, sorpresa! No se abría tampoco dicha aplicación.

En este punto es cuando me llaman y me dicen que el servidor "is dying quickly" y probablemente se deba a una infección de un virus (el argumento del virus es muy socorrido cuando no se tiene ni idea de qué está sucediendo; pero no, casi nunca es un virus).

Con la ceja levantada me puse (previa migración de toda la aplicación a otro servidor en producción) a analizar el asunto. Fue cuando además, descubrí el susto definitivo: no funcionaba la consola de sistema (la aplicación MMC) por lo que no conseguía abrir ni el Visor de Sucesos, ni la lista de Servicios, ni las políticas de Firewall, ni... ¡ni nada! Al abrir la MMC me daba el error Not enough storage is available to complete this operation.  Hummm....

Ni siquiera funcionaba el SFC /SCANNOW para restaurar archivos corrompidos; se detenía en el 74% dando también un error.

¿Qué estaba pasando?

La investigación y la solución (desesperada) al problema


Pues teníamos muy poca cosa. Un error, aparentemente, de permisos en Internet Explorer, y un desolador mensaje de Not enough storage is available to complete this operation al intentar abrir la consola MMC.

Dicho mensaje me mandó, obviamente, a comprobar el espacio en disco y memoria RAM, pese a que habían sido recientemente ampliados en la máquina virtual. Tal y como era de esperar, había espacio de sobra.

Todo lo que pude encontrar en Google hacía alusión a falta de espacio en disco, problemas al escribir archivos en %TEMP%, falta de RAM, etc. Sin embargo, ninguno de esos escenarios era parecido a este. Investigando sobre el error y mirando en el SDK de Windows, vemos que dicho error internamente corresponde al errorcode 14, ERROR_OUTOFMEMORY, cuya descripción hace alusión  a falta de recursos indirectos, (por ejemplo, falta de handles disponibles para el OS), es decir, que aunque lo parezca, no se refiere a falta de espacio físico de ningún tipo.

El número de handles de cada proceso se puede ver en el Administrador de Tareas, agregando la columna correspondiente. Pero tampoco era ese el caso y todas los procesos se mostraban con normalidad.

¿Qué en-el-infierno estaba pasando?

Fue entonces cuando recordé aquel viejo problema de las DLL mal registradas que, si bien los síntomas globales eran distintos, tenían en común que no podía abrirse la consola MMC (aunque el error mostrado tampoco coincidiera).

Ya hablamos en su momento de ese problema, y de cómo solucionarlo registrando las bibliotecas MSXML3.DLL y MSXML6.DLL.

¿Estaríamos ante ese viejo conocido? Rápidamente hice el consabido regsvr32 MSXML3.DLL  y el regsvr32 MSXML6.DLL y....

¡Nada de nada!

Pero el problema tenía que ser muy similar. ¿Y si la DLL mal registrada era simplemente otra? ¿Tendría que probar a registrarlas una a una? Fue cuando se me ocurrió usar algo totalmente old-school: decirle a la consola de texto que hiciese un regsvr32 a TODAS las DLL encontradas en los subdirectorios c:\windows\system32 y c:\windows\syswow64.

Para ello sólo hay que abrir el intérprete de comandos (el famoso CMD.exe al que los usuarios de Windows están tristemente acostumbrados) y escribir la siguiente cosa:

FOR /F %f IN ('dir %windir%\system32\*dll /B') DO regsvr32 %f /s

Así que probé y... ¡SÍ! Esta vez funcionó a la perfección.

El problema de esta solución es que no hemos podido averiguar cuál era la DLL díscola que provocó todo.

Sin embargo, la potencia de este método es que puede ser utilizado para muchos problemas típicos de Windows cuya solución no esté previamente documentada en otros lugares. Por tanto, cuando creáis que en vuestro Windows Server hay un polstergeist, o se trata de un X-File... probad este sistema.

Puede que sea la solución.