Por: M.A. Roberto Flores
Santiago
Email:
roberto.flores.consultoria (at) hotmail.com
En este pequeño artículo,
intentaré describir el camino que seguí y las herramientas que utilicé, para
cazar un bug, al cual agradezco mucho, ya que por su culpa aprendí muchas
cosas.
Empezare por describir la
aplicación en la cual el bug se manifestó (no sin antes gritar mas de un
improperio porque no aparecía, sin embargo si provocaba desmadres.)
- Sistema,
una descripción breve.
Recuerden que trabajo en una
empresa en la que debido a los acuerdos de confidencialidad, no puedo revelar
nombres de aplicaciones, ni lo que en realidad hace la aplicación, así que para
fines prácticos la llamaremos: Alien Proxy Server (recuerdan el tweet de Alien
Technology -> aqui).
La aplicación está construida
sobre .NET 4.0, lenguaje de programación C#, ORM Fluent NHibernate, DBMS
SQLite, IDE Visual Studio 2010, Utilizando Librerías desarrolladas en casa en
lenguaje C++ como DLLs.
Esta aplicación, utiliza entre
otras cosas, dos tipos de webservices, REST y SOAP para recibir la información,
procesarla y reenviarla (como todo proxy que se precie de serlo), a través de
sockets de .NET.
- Configuraciones
de Software en los que fue probado el sistema.
Windows 7 Ultimate, Windows
Server 2008 R2, Windows Vista, Windows XP SP3 Profesional.
- Configuraciones
de software
No requeridas.
Ingredientes para crearse un problema
parecido al que me paso (ver título del articulo), agregue librerías en C++
compiladas en modo DEBUG a su aplicación en
C#, compile y haga el PUBLISH de su aplicación, instale su aplicación en
la maquina donde fue desarrollada, y hasta aquí no tendrá aun ningún problema,
ahora bien, entregue la aplicación al usuario final, dígale que la instale y
pong….BUG a la vista, la aplicación se cayó.
El problema en si, es que le
sistema, hasta este punto no le dará a ud. Ningún inicio de donde carajos se
aloja el BUG, le indicara alguna línea mafufa de código y Ud. Empezara a cazar
el bug, aislar los módulos, a quitar funcionalidades, debido a que el fallo
solo sucede en las maquinas que no son de desarrollador, Ud. Incluso instalara
el IDE en alguna de las pcs, en las cuales existe el problema y el problema
desaparecerá como por arte de magia, no se engañe solo, el BUG aun está ahí,
solo que ud no lo sabe.
Después de varios días de
búsqueda sin saber que es, y de aislar módulos, funciones y demás parafernalia
developer, decide quitar todos los DLLs, recuerde que aun aquel mensaje de: DLL
not found in distributed application. Aun no ha hecho su aparición, así que al
quitar todos los DLLs en C++, su problema desaparece, bueno, si solo los
referencia sin utilizarlos, el programa funcionara en maquinas no developers,
pero eso no le ayuda en nada, lo que ud. Quisiera es no reescribir esas 4,000 líneas
de código en C#, porque el tiempo de entrega es para ayer.
Bueno, ya se dio cuenta que son
los DLLs, ahora se concentra con todo el poder de la fuerza e inicia la cacería
en serio, visita varios blogs, páginas de Microsoft, foros, stackoverflow.com,
en fin se mete ud. En lo más profundo de la ayuda en línea ayudado con la
herramienta más poderosa del universo: Google, bueno acompañado de su
ignorancia, porque sin ella, ud no estaría en esta penosa situación y con un
BUG de lo más desgraciado en su queridísima aplicación.
Bueno, para no darle más vueltas
al asunto, en algún momento, al correr la aplicación en una maquina no developer,
el famoso error sale a la luz: DLL not found in distributed application. --Hola
yo soy la causa de tus problemas—
Con esa misma frase, copy &
paste en google, segundos después, aparece una referencia a alguien que tuvo el
mismo grado de ignorancia que ud, el mismo error. – ver la liga en las
referencias—
En este caso, uno no lo cree,
pero así es, al compilar nuestras librerías DLLs en C++, se nos olvidó
compilarlas en modo reléase, las compilamos en modo DEBUG, eso conlleva a que
en mi caso particular, mi DLL, llama a un DLL de sistema, llamado: MSVCR100D.DLL
que solo existe en maquinas con un IDE instalado, porque como la letra D, al
final de su nombre lo indica, esas DLLs son para utilizarse en modo DEBUG, y no
existen en máquinas no developers, ok como llegué a esa conclusión. Bueno
aparte que lo leí en alguna de las ligas de referencia, en alguna de ellas me recomendaron
utilizar una herramienta llamada: dependency Walker –ver liga de
referencia—esta excelente herramienta, abre su ejecutable o DLL, y le dice a ud
con pelos y señales, todas las dependencias que deberían estar en presentes en
una máquina para que funcione correctamente, si alguna no estuviese presente,
el programita se lo señalara en amarillo, ¿Hermoso no? Procedemos a darnos cuenta
que esa librería es la que falta y que ho, no existe en ninguna maquina no
developer.
Solución: Proceda a compilar sus
librerías en C++ en modo reléase (Si Ud. esto ya lo sabía, siento mucho que
haya llegado hasta aquí). Referéncielas de nuevo en su proyecto C#, haga el
PUBLISH de su aplicación y su asunto quedara arreglado.
Si por curiosidad vuelve ud a
aplicarle la llave china con el Depedency Walker al DLL, se dará cuenta que
ahora la referencia es a la librería MSVCR100.DLL, si ud. Ve este nombre y lo
compara con el anteriormente detallado, el nombre difiere porque esta no tiene
una D. ahhhh, esta es la que está presente en todas las maquinas, sean
developer o no.
Referencias: