El caso del Internet Explorer que acaparaba la CPU al abrir una página

Recientemente, como “técnico de soporte familiar”, me ha tocado investigar y resolver un problema con Internet Explorer 6 en un perfil de usuario de Windows XP. El navegador se iniciaba correctamente, pero al intentar entrar en una página cualquiera la carga no avanzaba y el proceso Iexplore.exe comenzaba a consumir un tiempo de CPU excesivo.

La ventana respondía a las acciones de ratón y teclado, se podía detener el intento de carga de la página o cerrar la ventana. No obstante, era imposible usar Internet Explorer en estas condiciones. El problema no se daba en otros navegadores dentro de la misma sesión de usuario (¡hola, fanáticos anti-IE!), ni en otros perfiles.

Puesto que el contratiempo ocurrió de forma repentina y requería una solución urgente, no tuve ocasión de guardar información sobre instantáneas de pila, capturas de pantalla o claves del registro posiblemente involucradas. Por lo menos un detalle que recuerdo me ha permitido construir a posteriori una secuencia parcial de llamadas para ilustrar la situación:

ChildEBP RetAddr 
040dfc18 771e2e82 WININET!CCookieSettings::CCookieSettings
040dfc40 771e2fa2 WININET!CCookieSettings::GetSettings+0x29
040dfc54 771e55e6 WININET!CCookieSettings::GetSettings+0x24
040dfdc0 771b1957 WININET!EvaluateCookiePolicy+0xfd
040dfe68 7718cf94 WININET!HTTP_REQUEST_HANDLE_OBJECT::ExtractSetCookieHeaders+0xb9
040dfe84 7718cc4d WININET!HTTP_REQUEST_HANDLE_OBJECT::HttpSendRequest_Start+0x4a9
040dfe98 7718cb44 WININET!CFsm_HttpSendRequest::RunSM+0x59
040dfeb0 771a737b WININET!CFsm::Run+0x39
040dfee0 77f49588 WININET!CFsm::RunWorkItem+0x79
040dfef8 7c938182 SHLWAPI!ExecuteWorkItem+0x1d
040dff40 7c9381c3 ntdll!RtlpWorkerCallout+0x70
040dff60 7c938285 ntdll!RtlpExecuteWorkerRequest+0x1a
040dff74 7c93825c ntdll!RtlpApcCallout+0x11
040dffb4 7c80b6d9 ntdll!RtlpWorkerThread+0x87
040dffec 00000000 kernel32!BaseThreadStart+0x37

A primera vista una pila como esta no me sugería mucho; pensé que la causa sería alguna cookie almacenada que estuviera dañada. Sin embargo, eliminar las cookies no solucionó nada. Además borré los archivos temporales, sin apreciar mejora. Una traza de red tampoco mostraba anomalías; las peticiones HTTP y las respuestas del servidor web eran correctas. Introduje algunos nombres como EvaluateCookiePolicy o CCookieSettings en varios buscadores, esperando ver algún caso similar o remotamente relevante, y los resultados no fueron esclarecedores.

Al repasar una vez más la secuencia de llamadas, el nombre de la rutina EvaluateCookiePolicy adquirió sentido. Debía de estar relacionada con la evaluación de la  configuración del filtro de cookies que se introdujo en Internet Explorer 6, que determina qué cookies se aceptan y cuáles no. Entonces fui a la pestaña Privacidad de Opciones de Internet, donde encontré que la configuración vigente era Personalizada, por lo que no correspondía a ninguno de los seis niveles preestablecidos. No obstante, en la ventana de Opciones avanzadas no se encontraba marcada la casilla Sobrescribir la administración automática de cookies ni se recordaba haber importado archivo XML alguno con preferencias de privacidad especiales. Después de restablecer la configuración predeterminada de privacidad, el navegador recuperó sus funciones habituales.

¿Cómo es posible que el fallo ocurriera de un modo tan repentino, teniendo en cuenta que Internet Explorer había estado funcionado anteriormente ese día? Además, puesto que la configuración del filtro se almacena en el registro de Windows (de una manera un tanto misteriosa, eso sí), ¿qué clase de confusión había en los valores como para interpretarlos en general como configuración personalizada y que su análisis, que en condiciones normales invierte muy poco tiempo, desencadenara un bucle infinito? ¿Qué cambios concretos llevó a cabo la restauración de la configuración predeterminada para revertir la situación? Como solía decir el presentador de un antiguo programa de televisión en España, “eso… nunca lo sabremos”.

Por otra parte, el bucle infinito no bloqueaba la interfaz de usuario porque se originaba en un hilo auxiliar de trabajo (worker thread), como sugiere la aparición de la rutina RtlpWorkerThread en la base de la pila (obviando la rutina de inicio BaseThreadStart). La función principal del API de Windows para la creación de estos hilos auxiliares es QueueUserWorkItem, en Kernel32.dll, aunque el componente WinInet recurre a una función interna de Shlwapi.dll que ejecuta una labor similar, SHQueueUserWorkItem, apoyándose en la rutina anterior.

ChildEBP RetAddr 
00126fec 7c830a2e ntdll!RtlQueueWorkItem
00127000 77f49640 kernel32!QueueUserWorkItem+0x14
00127020 771a72fc SHLWAPI!SHQueueUserWorkItem+0xcf
00127048 771a90de WININET!CFsm::QueueWorkItem+0x1c

Y colorín colorado, este cuento se ha acabado.

2 thoughts on “El caso del Internet Explorer que acaparaba la CPU al abrir una página

  1. Pues… Sería magnífico poder averiguar si en las siguientes versiones de IE se “arrastró” este bug (porque está clarísimo que es un bug del código del IE), más que nada para poder meter un caso de soporte a Connect (quien pueda, eso sí 😉 ) para que lo puedan solventar en el actual IE8 (y tambien IE7 si es que siguen dando soporte, porque me parece que para IE6 ya no hay)

  2. PabloNetrix: para eso habría que reproducir el problema de manera consistente, primero en Internet Explorer 6 y luego en las otras versiones si fuera posible, pero faltan datos para una reconstrucción fiable. Si la suposición sobre las claves del registro que controlan la configuración del filtro de cookies fuese cierta, el procedimiento consistiría en manipular la información de sus valores con la intención de hallar algunos patrones que causen el fallo cada vez que se aplican. Esto puede necesitar investigaciones adicionales acerca del modo en que Internet Explorer analiza los valores de configuración para comprender el estado en que el código es susceptible de “quedarse colgado” en un bucle sin fin. De todas formas, dado el carácter excepcional de la situación, dudo mucho que Microsoft decida corregir el código y distribuir un parche, ni siquiera formando parte de un paquete acumulativo. Sin embargo, si se descubre las versiones 7 y 8 exhiben el mismo problema, quizá venga resuelto en la versión 9. 😉

    preguntoncojonero: era el programa Caiga Quien Caiga, en su primera etapa en Telecinco con El Gran Wyoming. Dije “antiguo” aunque en verdad no fue tanto, pues duró de 1996 a 2002.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *