Últimos mensajes - Powered by IBM
- Orientación de página
- error al intentar unirse al dominio
- Botones de acceso rapido en un teclado
- PROBLEMAS PARA CONFIGURAR IMPRESORA
- Crear mensaje de inicio en bacth
- Problema con cartel "Suspender Apagar Reiniciar"
- Error al encender laptop Pantalla Azul
- sesion lenta entre xp y winServer2008
- mensaje antes de responder un correo por xchange ...
- problemas con Z:
Palabras claves
[Articulo:] REPOSICION - El Final de las Infernales DLL's
05/07/2003 - 11:14 por JM Tella Llop [MS MVP] · | Informe spam
EL FINAL DE LAS INFERNALES DLL's
-
Muchas veces nos hemos enfrentado a la siguiente pregunta "Estoy intentando ejecutar una utilidad que instalé hace tiempo y funcionaba correctamente, y ahora, cada vez que la arranco, me saca un mensaje de error que dice:
"El ordinal 968 no puede ser localizado en la librería de acceso dinámico MFC42.DLL".
Una rápida mirada al sistema, nos muestra que la MFC42.DLL está instalada en cinco directorios y cada cual es más antigua que la anterior.
Existen muchas causas por las cuales podemos tener problemas con el problema de las DLL's: un mal instalador de programa que no chequea versiones antes de copiar una DLL en el directorio del sistema. Vamos a llamar TIPO 1 a este error de no respetar la version de una DLL al instalar. Es un problema muy común para los usuarios de Windows 9x, especialmente para aquellos que descargan software libre. El software profesional actual no suele causar este problema debido a que suelen chequear versiones antes de machacar una DLL.
Otra causa de error, llamemosle TIPO 2 o efecto colateral, es por cambios de funcionalidad en una nueva versión de una DLL. Se supone siempre que las DLL son compatibles hacia atrás, pero suele ser imposible garantizar un 100% de compatibilidad descendente.
Un conocido ejemplo de efecto colateral fueron los problemas ocurridos con el SP4 de NT 4. Cientos de usuarios informaron de "access violation" debido a intentar leer zonas no válidas de memoria al ejecutar aplicaciones que antes les estaban funcionando correctamente. El error estaba en la modificación de algunas DLLs del sistemas que empezaron a utilizar la función "realloc" para reasignar zonas propias de memoria. Simplemente la asignación "fija" de memoria, era una suposición de ciertos programadores "padres" de las aplicaciones que fallaban. Una suposición correcta hasta ese momento, que dejó de serlo al añadir MS nuevas funcionalidades a ciertas DLLs del sistema. Es muy peligrosos asumir cosas no documentadas y únicamente fruto de la experiencia. Ese fue el caso de aplicaciones mal desarrolladas, pero que estaban funcionando.
Y la tercera fuente de errores relacionados con las DLLs es cuando una nueva versión de una DLL introduce sin querer un nuevo bug. Es un caso menos frecuente, pero existe. Llamémosle, errores de TIPO 3.
¿POR QUÉ DLL's?
Antes de responder a esto, vamos a definir que és una DLL. DLL es un acrónimo de 'dynamic-link library' (o librería de acceso dinámico). Es decir, es un componente de software que una aplicación utiliza (monta) en tiempo de ejecución. Si por ejemplo, escribimos un programa que utiliza la función estándar 'strlen' (función que devuelve la longitud de una cadena de caracteres) y dinámicamente, nuestra aplicación enlaza con la MSVCRT.DLL, nuestro programa ejecutable no contendrá instrucciones para para 'strlen', lo único que contendrá es una instrucción de llamada a la dirección de 'strlen' en la MSVCRT.DLL. Cuando nuestro programa se ejecute, se cargará la MSVCRT.DLL la primera vez que el método sea utilizado.
Unix y Linux, distribuyen las aplicaciones como imágenes totalmente montadas (linked). A pesar que actualmente Unix y Linux soportan librerías compartidas (similares a las DLLs), prácticamente todos los fabricantes de software siguen distribuyendo las imágenes de programas con las librerías montadas estáticamente. Debido a que la aplicación, de esta manera, está totalmente autocontenida, la instalación de una nueva librería o aplicación no perjudicará al resto de los programas existentes.
** Afirmación 1: Las DLLs nos ahorran espacio en disco. Si tenemos 501 aplicaciones y utilidades que utilizan la MSVCRT.DLL, montando esta estáticamente en cada aplicación se incrementa el espacio utilizado en 500 veces el tamaño de la MSVCRT.DLL.
* Realidad: Las DLLs nos ahorra espacio, pero el espacio en disco, actualmente, es prácticamente ilimitado y cada vez más barato. Cuando el código común puede ser compartido a salvo, las DLLs son beneficionas.
** Afirmación 2: Las DLLs ahorran memoria al utilizar un técnica de memoria compartida llamada "mapeo de memoria". Windows carga las DLLs en la zona común global de memoria y mapea el rango de direcciones de la DLL en el espacio de direcciones de cada aplicación que hace la carga de dicha DLL. Por tanto, procesos diferentes que utilizan por ejemplo la MSVCRT.DLL, pueden compartir la misma instancia de la DLL en memoria sin necesidad de cargar copias de ella.
* Realidad: La mayoría de los procesos pueden cargar una DLL y son capaces de compartir una instancia global de la DLL. Compartir DLLs comunes nos proporciona un método significativo de ahorrar memoria de ejecución. Pero Windows no siempre es capaz de compartir una instancia de una DLL que es cargada por múltiples procesos.
Si hemos utilizado algun 'debugger' para probar una aplicación, probablemente hayamos visto un mensaje similar a este:
LDR: Automatic DLL Relocation in mipgm.exe.
LDR: Dll abc.dll base 10000000 relocated due to collision with c:\xyz\defg.dll
Cuando se crea una DLL, una dirección de base se especifica por el montador de enlace (linker) que sugiere a Windows en donde cargar este proceso en el espacio de direcciones de 32 bits. El valor por defecto en las DLLs creados con Visual C++ es 0x10000000. Consideremos ahora una DLL compartida (por ejemplo: abc.dll) que especifica 0x20000000 como petición de dirección de base. La aplicación a.exe se empieza a ejecutar cargando abc.dll en la direccion 0x20000000. La aplicación b.exe también usa la misam abc.dll pero imaginemos que ya ha cargado def.dll en la dirección 0x20000000. El sistema operativo, debe entonces cambiar la dirección de base (en inglés: 'rebasing') de abc.dll a una única direccion en el proceso b. Debido a que el proceso b, tiene esa direccion base asignada, el sistema operativo no puede compartir abc.dll. En este caso no ocurre el ahorro de memoria que habíamos mencionado anteriormente.
La mayoría de los procesos no necesitan reasignar la dirección base en cuyo caso el funcionamiento con DLLs sí que nos provoca un ahorro significativo de memoria.
De todas maneras, la memoria continúa bajando de precio, y por tanto, la cantidad de memoria empieza a no ser preocupante en las máquinas actuales.
** Afirmación 3: La localización de errores (bugs) es más sencilla debido a que un bug está típicamente localizado en una unica DLL. Por tanto no necesitamos redistribuir toda nuestra aplicación, sino únicamente la DLL errónea para solucionar un problema.
* Realidad: Las imágenes montadas estáticamente, no necesitan ser una única imagen como aplicación. Podemos tener la aplicación descompuesta en módulos montados estáticamente en el mismo directorio en el cual reside la aplicación. De hecho, esto es una aproximación de lo que Windows 2000 nos va a permitir.
La dualidad entre robustez y eficiencia dependen de la aplicación, el usuario y los recursos del sistema. Una situación ideal, sería aquella en que los fabricantes, usuarios y administradores del sistema deciden qué es más importante: funcionalidad o economía. Debido a que el coste de los ordenadores continúa bajando, el escoger economizar hoy puede ser una decisión errónea para el año siguiente.
WINDOWS FILE PROTECTION
-
Windows FIle Protection (WFP) protege a las DLL del sistema de ser actualizadas o borradas por agentes no autorizados. Las aplicaciones no pueden sustituir las DLLs del sistema. Únicamente los paquetes de actualización del sistema operativo com los SP (Service Packs) pueden hacer esto.
Las DLLs del sistema que pueden ser únicamente actualizadas por los SP se denominan DLLs protegidas. Hay aproximadamente 2800 DLLs protegidas en Windows 2000.
Si intentamos copiar una DLL protegida en el directorio del sistema, la copia, aparentemente, parecerá que es correcta y no veremos ningun mensaje de error. Pero Windows 2000 recuperará la DLL recientemente copiada con la DLL original silenciosamente.
WFP elimina completamente los errores de TIPO 1 definidos al comienzo de este artículo, y además minimiza los problemas de TIPO 2 y 3 causados por instalación / actualización de aplicaciones.
DLLs PRIVADAS
-
Las DLLs privadas son DLLs que son instalas con una aplicación específica y usadas sólo por esa aplicación. Por ejemplo, supongamos que yo soy el responsable de un programa llamada SuperApp.exe. Yo he 'testeado' ese programa con una versión x.x de la librería de Microsoft MSVCRT.DLL y una versión y.y de la SA.DLL (por ejemplo, SA.DLL no es una DLL de Microsoft, pero es una DLL de terceros distribuída con otras varias aplicaciones). Yo quiero asegurarme que mi programa SuperApp.exe siempre usará la MSVCRT.DLL versión x.x y la SA.DLL version y.y. Para hacer esto, mi instalador del producto copia SuperApp.exe, MSVCRT.DLL versión x.x y SA.DLL versión y.y en la carpeta .\SuperApp. Además debo notificar a Windows 2000, que SuperApp.exe debe utilizar esas DLLs privadas y únicamente esas (esto no es posible con Windows 9x). Cuando SuperApp.exe se ejecuta en Windwos 2000, este va a mirar en la carpeta .\SuperApp para localizar las DLLs de versión específica antes de mirar en las carpetas del sistema y en el path.
Los Service Packs futuros que actualicen al MSVCRT.DLL no harán fallar a la aplicación debido a que SuperApp.exe no utiliza la version compartida de MSVCRT.DLL. Otras aplicaciones que instalen diferentes versiones de SA.DLL tampoco afectarán a SuperApp.exe debido a que este, tiene su versión privada de SA.DLL.
Las DLLs privadas, se las denomina tambien DLLs únicas, debido a que utiliza una copia privada de esa DLL en lugar de la genérica. Si ejecutamos por ejemplo WordPad y SuperApp concurrentemente, dos copias de la MSVCRT.DLL serán cargadas en memoria.
Por tanto, como autores de la aplicación, podríamos registrar cada DLL o componente de la aplicación en el directorio de la aplicación en donde queremos que resida la copia privada.
Existe un segundo método que puede ser utilizado en aplicaciones ya existentes. Supongamos que c:\SuperApp\SuperApp.exe es una aplicación existente y que la queremos proteger de futuras actualizaciones de DLLs o incluso de actualizaciones debidas a los Service Packs. Simplemente copiamos las DLLs que queremos que sean privadas a SuperApp.exe a la carpeta .\SuperApp y creamos un fichero vacío en ese directorio llamado SuperApp.exe.local. De esta manerá el sistema sabe que cuando SuperApp.exe quiera cargar una DLL, debe buscarla siempre primero en donde esté ese fichero .local y buscará por tanto las DLLs y servidores COM en dicho directorio antes que en el path específico de Windows.
Ambas soluciones, la versión específica (en nuevas aplicaciones) y .local (en viejas aplicaciones) tienen las siguientes características:
* Las DLLs que están en el directorio de la aplicación son cargadas en lugar de las DLLs del sistema, aún cuando la función "LoadLibrary" de la aplicación tengan el camino 'hard-coded' ('a pelo', en castellano).
* No es posible redirigir la 20 KnownDLLs (conocidas DLLs), que están referenciadas en HKEY_LOCAL_MACHINE\SYSTEM\CurrentoControlSet\Control\SessionManager\KnownDLLs. Esta no pueden rodar independientemente ya que necesitan mantener estados de procesos cruzados. Por ejemplo: kernel32, user32 y ole32 no pueden ser redirigidas debido a que tienen estados (objetos del kernel, manejadores de ventanas) que necesitan existir a lo largo de todos los procesos. En futuras versiones del sistema operativo estas limitaciones quedarán mas restringidas.
Jose Manuel Tella Llop
MS MVP - DTS
jmtella@compuserve.com
13 - junio - 2001
Jose Manuel Tella Llop
MS MVP - DTS
jmtella@compuserve.com
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningún derecho.
This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.
-
Muchas veces nos hemos enfrentado a la siguiente pregunta "Estoy intentando ejecutar una utilidad que instalé hace tiempo y funcionaba correctamente, y ahora, cada vez que la arranco, me saca un mensaje de error que dice:
"El ordinal 968 no puede ser localizado en la librería de acceso dinámico MFC42.DLL".
Una rápida mirada al sistema, nos muestra que la MFC42.DLL está instalada en cinco directorios y cada cual es más antigua que la anterior.
Existen muchas causas por las cuales podemos tener problemas con el problema de las DLL's: un mal instalador de programa que no chequea versiones antes de copiar una DLL en el directorio del sistema. Vamos a llamar TIPO 1 a este error de no respetar la version de una DLL al instalar. Es un problema muy común para los usuarios de Windows 9x, especialmente para aquellos que descargan software libre. El software profesional actual no suele causar este problema debido a que suelen chequear versiones antes de machacar una DLL.
Otra causa de error, llamemosle TIPO 2 o efecto colateral, es por cambios de funcionalidad en una nueva versión de una DLL. Se supone siempre que las DLL son compatibles hacia atrás, pero suele ser imposible garantizar un 100% de compatibilidad descendente.
Un conocido ejemplo de efecto colateral fueron los problemas ocurridos con el SP4 de NT 4. Cientos de usuarios informaron de "access violation" debido a intentar leer zonas no válidas de memoria al ejecutar aplicaciones que antes les estaban funcionando correctamente. El error estaba en la modificación de algunas DLLs del sistemas que empezaron a utilizar la función "realloc" para reasignar zonas propias de memoria. Simplemente la asignación "fija" de memoria, era una suposición de ciertos programadores "padres" de las aplicaciones que fallaban. Una suposición correcta hasta ese momento, que dejó de serlo al añadir MS nuevas funcionalidades a ciertas DLLs del sistema. Es muy peligrosos asumir cosas no documentadas y únicamente fruto de la experiencia. Ese fue el caso de aplicaciones mal desarrolladas, pero que estaban funcionando.
Y la tercera fuente de errores relacionados con las DLLs es cuando una nueva versión de una DLL introduce sin querer un nuevo bug. Es un caso menos frecuente, pero existe. Llamémosle, errores de TIPO 3.
¿POR QUÉ DLL's?
Antes de responder a esto, vamos a definir que és una DLL. DLL es un acrónimo de 'dynamic-link library' (o librería de acceso dinámico). Es decir, es un componente de software que una aplicación utiliza (monta) en tiempo de ejecución. Si por ejemplo, escribimos un programa que utiliza la función estándar 'strlen' (función que devuelve la longitud de una cadena de caracteres) y dinámicamente, nuestra aplicación enlaza con la MSVCRT.DLL, nuestro programa ejecutable no contendrá instrucciones para para 'strlen', lo único que contendrá es una instrucción de llamada a la dirección de 'strlen' en la MSVCRT.DLL. Cuando nuestro programa se ejecute, se cargará la MSVCRT.DLL la primera vez que el método sea utilizado.
Unix y Linux, distribuyen las aplicaciones como imágenes totalmente montadas (linked). A pesar que actualmente Unix y Linux soportan librerías compartidas (similares a las DLLs), prácticamente todos los fabricantes de software siguen distribuyendo las imágenes de programas con las librerías montadas estáticamente. Debido a que la aplicación, de esta manera, está totalmente autocontenida, la instalación de una nueva librería o aplicación no perjudicará al resto de los programas existentes.
** Afirmación 1: Las DLLs nos ahorran espacio en disco. Si tenemos 501 aplicaciones y utilidades que utilizan la MSVCRT.DLL, montando esta estáticamente en cada aplicación se incrementa el espacio utilizado en 500 veces el tamaño de la MSVCRT.DLL.
* Realidad: Las DLLs nos ahorra espacio, pero el espacio en disco, actualmente, es prácticamente ilimitado y cada vez más barato. Cuando el código común puede ser compartido a salvo, las DLLs son beneficionas.
** Afirmación 2: Las DLLs ahorran memoria al utilizar un técnica de memoria compartida llamada "mapeo de memoria". Windows carga las DLLs en la zona común global de memoria y mapea el rango de direcciones de la DLL en el espacio de direcciones de cada aplicación que hace la carga de dicha DLL. Por tanto, procesos diferentes que utilizan por ejemplo la MSVCRT.DLL, pueden compartir la misma instancia de la DLL en memoria sin necesidad de cargar copias de ella.
* Realidad: La mayoría de los procesos pueden cargar una DLL y son capaces de compartir una instancia global de la DLL. Compartir DLLs comunes nos proporciona un método significativo de ahorrar memoria de ejecución. Pero Windows no siempre es capaz de compartir una instancia de una DLL que es cargada por múltiples procesos.
Si hemos utilizado algun 'debugger' para probar una aplicación, probablemente hayamos visto un mensaje similar a este:
LDR: Automatic DLL Relocation in mipgm.exe.
LDR: Dll abc.dll base 10000000 relocated due to collision with c:\xyz\defg.dll
Cuando se crea una DLL, una dirección de base se especifica por el montador de enlace (linker) que sugiere a Windows en donde cargar este proceso en el espacio de direcciones de 32 bits. El valor por defecto en las DLLs creados con Visual C++ es 0x10000000. Consideremos ahora una DLL compartida (por ejemplo: abc.dll) que especifica 0x20000000 como petición de dirección de base. La aplicación a.exe se empieza a ejecutar cargando abc.dll en la direccion 0x20000000. La aplicación b.exe también usa la misam abc.dll pero imaginemos que ya ha cargado def.dll en la dirección 0x20000000. El sistema operativo, debe entonces cambiar la dirección de base (en inglés: 'rebasing') de abc.dll a una única direccion en el proceso b. Debido a que el proceso b, tiene esa direccion base asignada, el sistema operativo no puede compartir abc.dll. En este caso no ocurre el ahorro de memoria que habíamos mencionado anteriormente.
La mayoría de los procesos no necesitan reasignar la dirección base en cuyo caso el funcionamiento con DLLs sí que nos provoca un ahorro significativo de memoria.
De todas maneras, la memoria continúa bajando de precio, y por tanto, la cantidad de memoria empieza a no ser preocupante en las máquinas actuales.
** Afirmación 3: La localización de errores (bugs) es más sencilla debido a que un bug está típicamente localizado en una unica DLL. Por tanto no necesitamos redistribuir toda nuestra aplicación, sino únicamente la DLL errónea para solucionar un problema.
* Realidad: Las imágenes montadas estáticamente, no necesitan ser una única imagen como aplicación. Podemos tener la aplicación descompuesta en módulos montados estáticamente en el mismo directorio en el cual reside la aplicación. De hecho, esto es una aproximación de lo que Windows 2000 nos va a permitir.
La dualidad entre robustez y eficiencia dependen de la aplicación, el usuario y los recursos del sistema. Una situación ideal, sería aquella en que los fabricantes, usuarios y administradores del sistema deciden qué es más importante: funcionalidad o economía. Debido a que el coste de los ordenadores continúa bajando, el escoger economizar hoy puede ser una decisión errónea para el año siguiente.
WINDOWS FILE PROTECTION
-
Windows FIle Protection (WFP) protege a las DLL del sistema de ser actualizadas o borradas por agentes no autorizados. Las aplicaciones no pueden sustituir las DLLs del sistema. Únicamente los paquetes de actualización del sistema operativo com los SP (Service Packs) pueden hacer esto.
Las DLLs del sistema que pueden ser únicamente actualizadas por los SP se denominan DLLs protegidas. Hay aproximadamente 2800 DLLs protegidas en Windows 2000.
Si intentamos copiar una DLL protegida en el directorio del sistema, la copia, aparentemente, parecerá que es correcta y no veremos ningun mensaje de error. Pero Windows 2000 recuperará la DLL recientemente copiada con la DLL original silenciosamente.
WFP elimina completamente los errores de TIPO 1 definidos al comienzo de este artículo, y además minimiza los problemas de TIPO 2 y 3 causados por instalación / actualización de aplicaciones.
DLLs PRIVADAS
-
Las DLLs privadas son DLLs que son instalas con una aplicación específica y usadas sólo por esa aplicación. Por ejemplo, supongamos que yo soy el responsable de un programa llamada SuperApp.exe. Yo he 'testeado' ese programa con una versión x.x de la librería de Microsoft MSVCRT.DLL y una versión y.y de la SA.DLL (por ejemplo, SA.DLL no es una DLL de Microsoft, pero es una DLL de terceros distribuída con otras varias aplicaciones). Yo quiero asegurarme que mi programa SuperApp.exe siempre usará la MSVCRT.DLL versión x.x y la SA.DLL version y.y. Para hacer esto, mi instalador del producto copia SuperApp.exe, MSVCRT.DLL versión x.x y SA.DLL versión y.y en la carpeta .\SuperApp. Además debo notificar a Windows 2000, que SuperApp.exe debe utilizar esas DLLs privadas y únicamente esas (esto no es posible con Windows 9x). Cuando SuperApp.exe se ejecuta en Windwos 2000, este va a mirar en la carpeta .\SuperApp para localizar las DLLs de versión específica antes de mirar en las carpetas del sistema y en el path.
Los Service Packs futuros que actualicen al MSVCRT.DLL no harán fallar a la aplicación debido a que SuperApp.exe no utiliza la version compartida de MSVCRT.DLL. Otras aplicaciones que instalen diferentes versiones de SA.DLL tampoco afectarán a SuperApp.exe debido a que este, tiene su versión privada de SA.DLL.
Las DLLs privadas, se las denomina tambien DLLs únicas, debido a que utiliza una copia privada de esa DLL en lugar de la genérica. Si ejecutamos por ejemplo WordPad y SuperApp concurrentemente, dos copias de la MSVCRT.DLL serán cargadas en memoria.
Por tanto, como autores de la aplicación, podríamos registrar cada DLL o componente de la aplicación en el directorio de la aplicación en donde queremos que resida la copia privada.
Existe un segundo método que puede ser utilizado en aplicaciones ya existentes. Supongamos que c:\SuperApp\SuperApp.exe es una aplicación existente y que la queremos proteger de futuras actualizaciones de DLLs o incluso de actualizaciones debidas a los Service Packs. Simplemente copiamos las DLLs que queremos que sean privadas a SuperApp.exe a la carpeta .\SuperApp y creamos un fichero vacío en ese directorio llamado SuperApp.exe.local. De esta manerá el sistema sabe que cuando SuperApp.exe quiera cargar una DLL, debe buscarla siempre primero en donde esté ese fichero .local y buscará por tanto las DLLs y servidores COM en dicho directorio antes que en el path específico de Windows.
Ambas soluciones, la versión específica (en nuevas aplicaciones) y .local (en viejas aplicaciones) tienen las siguientes características:
* Las DLLs que están en el directorio de la aplicación son cargadas en lugar de las DLLs del sistema, aún cuando la función "LoadLibrary" de la aplicación tengan el camino 'hard-coded' ('a pelo', en castellano).
* No es posible redirigir la 20 KnownDLLs (conocidas DLLs), que están referenciadas en HKEY_LOCAL_MACHINE\SYSTEM\CurrentoControlSet\Control\SessionManager\KnownDLLs. Esta no pueden rodar independientemente ya que necesitan mantener estados de procesos cruzados. Por ejemplo: kernel32, user32 y ole32 no pueden ser redirigidas debido a que tienen estados (objetos del kernel, manejadores de ventanas) que necesitan existir a lo largo de todos los procesos. En futuras versiones del sistema operativo estas limitaciones quedarán mas restringidas.
Jose Manuel Tella Llop
MS MVP - DTS
jmtella@compuserve.com
13 - junio - 2001
Jose Manuel Tella Llop
MS MVP - DTS
jmtella@compuserve.com
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningún derecho.
This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.
Preguntas similares
- [Artículo] Entendiendo el registro de windows - FINAL (parte IV)
- [Artículo] Entendiendo el registro de windows (Parte III y final???)
Busqueda sugerida :
Leer las respuestas