martes, febrero 20, 2007

Una curiosidad sobre la caja Ejecutar

En uno de los foros en los que participo, un usuario tenía la siguiente inquietud: ¿Por qué si en una ventana de comandos se escribe "msconfig" no se reconoce el comando y, en cambio, desde Inicio, Ejecutar, sí se ejecuta correctamente dicha herramienta?

El secreto está en que la caja Ejecutar del menú Inicio invoca a una función muy específica (y útil): ShellExecuteEx. Es ella la que realiza todo el trabajo "sucio" de encontrar lo que se ha escrito en la caja Ejecutar. Simplificando detalles que no son relevantes en el tema de este artículo, en primer lugar ShellExecuteEx va a mirar en la clave de Registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths. Las aplicaciones pueden incluir las rutas de sus ejecutables en esta clave sin necesidad de manipular la variable de entorno Path. En el caso de que no haya encontrado el ejecutable en la clave anterior, la función ShellExecuteEx se dispondrá a examinar la variable de entorno Path del sistema operativo. Esto lo hace llamando a la función PathFindOnPath, públicamente documentada. Esta función hace uso a su vez de FindFirstFileEx, FindNextFile y FindClose para encontrar el archivo en cada ruta que encuentre en la variable antes mencionada. Estas funciones residen en Kernel32.dll, por lo que realizan la búsqueda utilizando para ello ciertas funciones del núcleo de Windows que no están públicamente documentadas. Desde símbolo de sistema sólo se examina el contenido de la variable de entorno Path para buscar un comando no interno. Como la ruta de Msconfig.exe no está por defecto en el contenido de la variable Path, aparece un mensaje de error indicando que el comando no ha sido reconocido.

Como siempre, muchos virus se aprovechan de esto y redireccionan el contenido de la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths para que apunte a su código malicioso. Así, el usuario, que inocentemente trata de ejecutar Regedit o Msconfig para reparar su sistema, acaba ejecutando un troyano o el ejecutable de un gusano, por ejemplo.

Por cierto, las funciones FindFirstFileEx, FindNextFile y FindClose antes mencionadas las utiliza Windows en muchísimos contextos. Como curiosidad, en el artículo donde comentaba cómo Agregar o quitar programas obtenía la información sobre el tamaño de los programas instalados, el módulo Appwiz.cpl llama a estas funciones si no hay información en la caché o ésta se ha corrompido.

lunes, febrero 05, 2007

Sobre el desfragmentador de Windows Vista

Reproduzco una consulta que recibí de un usuario:

Daniel, el desfragmentador de Windows Vista pienso que es bastante malo, ¿qué han hecho los chicos de MS? No hay barra de progreso y, lo que es más importante, si analizo una partición desfragmentada desde Vista aún sigo viendo mucha fragmentación. ¿Cómo lo han empeorado tanto?

Aunque le parezca lo contrario, el desfragmentador incluido en Windows Vista es mucho mejor que el de su predecesor. En este artículo discutiré cómo funciona internamente, centrándome en las quejas más frecuentes que he ido recibiendo.

¿Por qué no hay barra de progreso al desfragmentar?

Una barra de progreso en un proceso de desfragmentación es una incorrección. Todo proceso de desfragmentación del espacio en disco es un proceso en el cual se siguen múltiples fases: una para desfragmentar archivos, otra para consolidar el espacio libre en disco, etc. Cada una de estas fases puede durar un tiempo variable, por lo que la barra de progreso del desfragmentador de Windows XP carece de sentido práctico.

Los resultados del desfragmentador difieren de los del de XP

En efecto, el desfragmentador de Windows Vista utiliza un algoritmo distinto del de Windows XP. Es mucho más eficiente. El algoritmo empleado en Windows XP podría simplificarse del modo siguiente: Todo archivo del disco que esté en, al menos, dos posiciones no contiguas del disco se marca como "fragmentado". El desfragmentador obtendrá ese dato y unirá todas las partes para, posteriormente, compactar el espacio libre en disco. Esto supone dos puntos negativos:
  • Se requiere de un cierto espacio libre en disco para poder realizar la desfragmentación. En el caso de Windows XP este espacio mínimo es de un 15%. En Windows Vista no hay espacio libre mínimo necesario.
  • Si los fragmentos son "demasiado grandes" el tiempo empleado en mover los bloques es superior a la ganancia en rendimiento obtenida.
Quiero precisar sobre el último punto: En un volumen NTFS, el salto de un fragmento a otro consume un bajísimo porcentaje de tiempo en comparación con el tiempo que se tarda en leer un bloque no fragmentado. Partiendo de bloques de 64 MB o más, no merece la pena mantenerlos contiguos, el "esfuerzo" necesario para ello no compensa la ganancia de rendimiento. Debido a esta optimización, el desfragmentador de Vista reduce el consumo de CPU de manera considerable.

El desfragmentador hace uso de la característica "Low-priority I/Os" de Windows Vista

Una de las nuevas posibilidades del núcleo de Windows Vista que más me gusta son las "low-priority I/Os". Así, un desarrollador, que antes podía ejecutar procesos con baja prioridad, ahora puede realizar entradas/salidas igualmente con baja prioridad. En Windows Vista el servicio de indizado, Windows Defender, las aplicaciones que se inician con Windows, y el desfragmentador (entre otros) hacen uso de entradas/salidas de baja prioridad.

El objetivo de Microsoft es que el usuario pueda desfragmentar el disco mientras utiliza cómodamente el PC. Todo el proceso de desfragmentación se hace empleando entradas/salidas de baja prioridad en el momento que se detecte actividad en el sistema. La única excepción es la fase en la que se desfragmenta la MFT del disco. Puede hacer la prueba, inicie el proceso de desfragmentación, deje el sistema sin usarlo y observe el consumo de recursos. Efectivamente es alto, pero ahora realice tareas en el sistema, verá como el consumo disminuye (aumentará lógicamente el tiempo de desfragmentado).

Hay una tarea programada que desfragmenta el disco

Windows Vista incorpora una tarea programada para desfragmentar el disco. Puede acceder a ella desde Administración de equipos, Herramientas del sistema, Programador de tareas, Biblioteca del Programador de tareas, Microsoft, Windows, Defrag. Esta tarea sólo se realiza cuando el sistema está inactivo, por lo que si despliega la pestaña Historial quizá observe que la tarea se ha iniciado, detenido e iniciado de nuevo un sinfín de veces. Es normal, se detectó actividad en el equipo y la tarea se detuvo, para continuarse tan pronto como el sistema vuelva a estar inactivo.

Así pues, ya ve que el desfragmentador incluido en Windows Vista es mucho más eficiente y menos intrusivo que el de Windows XP, a pesar de que la interfaz gráfica sea demasiado "simple" y esto pueda confundir a los usuarios.

Una última optimización del desfragmentador de Windows Vista que no quiero dejar sin comentar tiene que ver con el almacén de copias sombra ("shadow copies"): El nuevo algoritmo de desfragmentación está diseñado del tal forma que se reduce el número de operaciones copy-on-write en el disco. Si esto no fuera así, el almacén de copias sombra y puntos de restauración de Windows Vista vería acelerado su llenado, perdiéndose por tanto el contenido más antiguo del mismo.

martes, enero 23, 2007

Ese "extraño" mensaje: La memoria no se puede "read"

Uno de los problemas que más recibo y que pienso que más despista a la gente es un error del tipo "La instrucción en "0xnúmero_hexadecimal" hace referencia a la memoria en "0xnúmero_hexadecimal". La memoria no se puede "written"/"read". Observe la siguiente imagen que ilustra el error:

Mensaje de error de aplicación

Mucha gente asocia este mensaje de error con un problema con la memoria RAM, pensando que pudiera estar dañada o que quede poca disponible. Probablemente el problema no se deba a un módulo defectuoso de RAM.

Ese mensaje de error es la manera "fea" que tiene Windows XP de decir que ha ocurrido una excepción en modo usuario porque alguna aplicación o componente ha intentado acceder a una posición de memoria que no debería (por ejemplo, mediante un puntero erróneo). Esto se denomina infracción de acceso y se identifica mediante el código de error c0000005.

Veamos un poco qué ocurre por dentro de Windows cuando sucede un error de este tipo

Windows debe tener un mecanismo interno que le permita actuar de algún modo cuando ocurra una excepción no controlada en modo usuario. Para simplificar las cosas, supongamos que se trata de un bloque try convencional que puede lanzar la excepción mediante la función UnhandledExceptionFilter. En este momento, Windows examina el Registro para saber qué hacer una vez ha ocurrido un error de aplicación. La clave HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug contiene un valor Auto que le indica al sistema si debe iniciar automáticamente el depurador por defecto del sistema, definido éste en el valor Debugger. El depurador por defecto de Windows XP es Dr Watson.


Nota: Si instala alguna aplicación relacionada con el desarrollo, es probable que ésta instale su propio depurador. Quizá también lo establezca automáticamente como depurador por defecto del sistema.


En este momento se carga la dll Faultrep.dll que examina el Registro para saber cómo desea el usuario que se le informe de los errores de aplicación. La clave de Registro HKLM\SOFTWARE\Microsoft\PCHealth\ErrorReporting contiene la información accesible desde la interfaz gráfica de Windows en el panel Informe de errores, situado en la pestaña Opciones avanzadas de Propiedades de sistema. Observe la siguiente imagen:

Panel Informe de errores de Windows XP

Si se desea que se muestre una intuitiva interfaz gráfica (valor ShowUI distinto de cero), Windows cargará el proceso \WINDOWS\system32\Dwwin.exe en memoria, que es el que muestra la típica pantalla de error de aplicación de Windows XP, mostrada en la siguiente imagen:

Típica ventana de error de aplicación de Windows XP

Si el valor ShowUI es igual a cero, siempre obtendrá la pantalla mostrada al principio del artículo, que no ofrece la posibilidad de ver el módulo afectado por el error ni de enviar la información a Microsoft. Dependiendo de la aplicación que haya generado el error, es posible que se le muestre esta pantalla pese a que utilice la configuración por defecto. No debe preocuparse, se trata del mismo problema: una excepción no controlada en modo usuario.

¿Cómo solucionar el problema?

En primer lugar debe asegurarse de que el sistema esté libre de virus y ficheros espía. Un sistema infectado puede producir excepciones de este tipo. En segundo lugar, revise la esquina superior izquierda del título de la ventana de error, es posible que se haga referencia a un fichero de terceros conocido, en cuyo caso habría que contactar con el fabricante para informarse de si es un problema conocido o de si existe alguna solución al respecto.

Si el proceso referenciado fuese demasiado inespecífico (como por ejemplo Explorer.exe), no queda más remedio que hacer pruebas iniciando el sistema en Modo seguro o realizar sucesivos inicios limpios hasta dar con el posible culpable.

También es posible examinar la información registrada por el depurador de programa.

Nota: Si el proceso referenciado fuese Iexplore.exe, es posible que algún añadido (plug-in) sea el que ha generado la excepción. Si usa Internet Explorer 7, ejecute el navegador sin complementos y observe si se reproduce el problema. Para ejecutar el navegador sin complementos abra Inicio, Ejecutar, escriba "%ProgramFiles%\Internet Explorer\iexplore.exe" -extoff y pulse Aceptar.


En este caso deberá pulsar sobre Cancelar en la ventana de error para depurarlo. Abra Inicio, Ejecutar, escriba "%AllUsers%\Datos de programa\Microsoft\Dr Watson" (con comillas) y pulse Aceptar. Observará dos ficheros: Drwtsn32.log contiene un reporte con todos los errores de aplicación que han sido administrados por Dr Watson. Los últimos errores recibidos se sitúan al final de la lista. User.dmp suele ser un pequeño volcado de la memoria en el momento del error. Este fichero se sobreescribe cada vez que ocurre un error de aplicación. Puede cargar este fichero en cualquier depurador como Windbg (http://www.microsoft.com/whdc/devtools/debugging/default.mspx) para examinarlo.

Espero que este artículo haya aclarado algunas dudas acerca de esa "extraña" ventana que nos indica que la memoria no se puede "read" (o "written") y que nos podemos encontrar cuando nos topamos con software mal diseñado en nuestro sistema.