Como seguramente has podido suponer por las entradas anteriores en mi blog y en otros artículos, me gusta saber exactamente que hace mi sistema. Quiero saber si un proceso consume demasiada CPU, provocando agobios en memoria, o demasiado trabajo en disco. A parte de mantener mis ordenadores funcionando correctamente, vigilarlos a veces me ayuda a encontrar problemas de rendimiento y fiabilidad en el código de terceros para Windows.
Lo primero que hago es configurar Process Explorer para que se ejecute automáticamente cuando inicio una sesión de Windows. Siempre que configuro un ordenador nuevo, añado un acceso directo a Process Explorer en la carpeta de Inicio de mi perfil incluyendo el parámetro /minimize. De esta forma, Process Explorer se ejecuta oculto con un icono en la barra de notificación donde muestra una pequeña vista histórica del nivel de actividad de la CPU. Como quiero tener información detallada sobre los procesos del sistema a parte de los míos, también especifico el parámetro /e en Vista, y con esto Windows presenta una ventana del UAC que me permite dar a Process Explorer permisos administrativos.
Hace unos meses atrás empezé a utilizar un portátil, y notaba a veces lentitud en el sistema. El icono de Process Explorer confirmaba mi percepción visualizando un mini-gráfico de actividad roja en la CPU. Cuando ubiqué el ratón en el icono, éste abrió una ventana indicando el nombre del proceso que estaba consumiendo más CPU, y en este caso mostraba el proceso de Sistema (System) como responsable:
Las primeras veces que ví el problema, al poco se resolvía sólo y no me daba tiempo a investigarlo. En cualquier caso pude ver, mediante la ventana de Información del Sistema de Process Explorer, que los picos de CPU eran bastante significativos:
El proceso de Sistema es especial porque no tiene un archivo ejecutable como los otros procesos. Sólo funciona para hilos del sistema operativo como el administrador de memoria, el administrador de caché, y otros subsistemas, así como para hilos de los drivers. Estos hilos se ejecutan completamente en modo kernel, y por eso el consumo de CPU por parte del proceso de Sistema aparece en rojo en los gráficos de Process Explorer.
Sospeché que un driver de un tercero era la causa del problema, por eso el primer paso en mi investigación fué localizar el hilo que más CPU consumía para llegar al culpable. Empezé a buscar los picos de CPU y cuando ví uno hice doble click en el proceso del Sistema y fuí a la pestaña "Threads" para ver los hilos. Allí ví el pico de CPU:
El prefijo “ntkrnlpa.exe” en cada dirección de inicio de un hilo lo identifica como un hilo del sistema operativo, y éstos eran los que más consumo de CPU tenían (Ntkrnlpa.exe es la versión cargada de kernel en sistemas cliente de 32-bit que no se ejecuta en memoria protegida o en sistemas servidores que necesitan direccionar más de 4GB de memoria). Debido a que antes configuré Process Explorer para recuperar los símbolos de los ejecutables del sistema operativo del servidor público de símbolos de Microsoft, la lista de hilos también mostraba los nombres de los hilos de las funciones de inicio. Los hilos más activos comienzan con la función ExpWorkerThread, que quiere decir que son hilos que trabajan para los drivers y para el sistema. En lugar de crear hilos dedicados que consumen recursos de memoria, los drivers y el sistema pueden lanzar trabajos al contenedor compartido worker threads del sistema operativo.
El proceso de Sistema es un tipo especial de proceso llamado "proceso protegido" que no permite ningún tipo de acceso a sus hilos o memoria. Los procesos protegidos existen para dar servicio a la Administración de Derechos Digitales (DRM), y con esto, los proveedores de contenido de alta definición pueden guardar claves de cifrado para sus contenidos reduciendo el riesgo de que un usuario con privilegios administrativos pueda utilizar herramientas anti-DRM para llegar al proceso y leer las claves.
Con este intento fallido, tenía que encontrar otra forma de ver lo que estaban haciendo los worker threads. Para ello utilicé KernRate, una herramienta de línea de comandos de descarga gratuita de Microsoft. KernRate puede capturar los procesos en modo usuario y los hilos en modo kernel. KernRate utiliza un recolector que ya utilizó la primera versión de Windows NT, que registra las direcciones únicas que la CPU ejecuta en un momento dado. Cuando paras la captura, KernRate recupera la información del kernel, mapea las direcciones de los drivers cargados, y puede incluso utilizar el motor de símbolos para mostrar los nombres de las funciones.
En primer lugar los picos estaban en el kernel, y en segundo lugar estaba un driver que no conocía: b57nd60x. La mayoría de los archivos de los drivers están en %systemroot%\system32\drivers, y podría abrir esa carpeta para ver las propiedades del archivo, pero tenía abierto Process Explorer y era más rápido comprobar el fabricante del driver y la versión desde la vista de los DLL del proceso de Sistema. La vista de los DLL mostraba las DLLs y los archivos mapeados dentro del espacio de direcciones de los procesos en modo usuario, y para el proceso de Sistema mostraba los módulos del kernel, incluyendo los drivers cargados en el sistema. La vista de las DLL revelaba que el driver era de la tarjeta de red del portátil, fabricado por Broadcom y con versión 10.10:
Ahora que descubrí que el driver de Broadcom era el causante del gran consumo de CPU, el siguiente paso fue ver si había alguna versión nueva disponible. Fuí a la página de descarga de Dell para mi sistema, pero no encontré nada. Sospechando que lo que descubrí tendría que haber ocurrido ya antes, decidí notificarlo a Broadcom. Utilicé los contactos del equipo de sistemas hardware aquí en Microsoft para encontrar el representante del driver de Broadcom y escribirle un correo electrónico detallando la descripción de los síntomas y mi investigación. Él reenvió el email al desarrollador del driver, quien no conocía la causa y me dijo que en unos días me enviaría una versión depurada del driver con símbolos para que KernRate capturara las funciones del driver que provocaban los picos de CPU. El problema ocurrió de nuevo unos días más tarde y le envié de vuelta los resultados de KernRate con la información de las funciones.