2008-12-15 6 views
13

Después de implementar nuestro enorme sistema distribuido a uno de nuestros clientes, experimentamos un error inesperado. Durante la investigación, reemplazamos el conjunto causando el error con uno en el que hemos agregado algún código de diagnóstico. El dll que usamos está construido en modo de depuración. ¡Y de repente todo funciona!Cuando los dlls de lanzamiento no funcionan pero los dlls de depuración hacen

Reemplazando el dll de depuración con la versión de lanzamiento (con el código de diagnóstico) hace que se bloquee de nuevo.

No hay directivas de precompiladores, atributos de depuración condicional, etc. en nuestro código. El problema se ha encontrado en dos sitios de instalación diferentes, mientras que funciona bien en varios más.

(El proyecto tiene una mezcla de C# y VB.NET, el montaje es troublesom VB.NET .., si hay alguna diferencia)

Así que la pregunta es: ¿Qué se hace en situaciones ¿Me gusta esto? ¿Y cuál puede ser la causa, en general? Cualquier consejo sobre la depuración de este problema es bienvenido.

+0

Podría ser útil dar algunos detalles sobre el problema, aparte de general "funciona en depuración pero no en versión". ¿Qué es "eso", qué es "eso"? – Will

+0

No he podido bloquearlo todavía, pero es una excepción de referencia nula (por lo que realmente no ayuda, ¿verdad?). –

+1

Podría, junto con la pila de llamadas. Examinar el callstack es una de las primeras cosas que debes hacer. – Will

Respuesta

12

Por causas ... bueno, algún indicio del síntoma ayudaría. Una posibilidad es que tenga un código para un método como Debug.WriteLine que tiene efectos secundarios (es decir, lo hace funcionar). Las llamadas a los métodos marcados con [Conditional(...)] no se compilan a menos que tenga los símbolos correctos definidos, por lo que cualquier elemento marcado [Conditional("DEBUG")] se eliminará en silencio.

También podría ser un error del compilador, pero eso es un poco improbable (pero no imposible).

¿Cuál es el síntoma? ¿Cómo se rompe?

Como ejemplo de lo anterior:

static string Bar { get; set; } 
    static void Main() 
    { 
     Bar = "I'm broken"; 
     Debug.WriteLine(Foo()); 
     Console.WriteLine(Bar); 
    } 
    // note Foo only called in DEBUG builds 
    static string Foo() 
    { 
     Bar = "I'm working"; 
     return "mwahahah"; 
    } 

Compilado en modo de depuración se imprime "Estoy trabajando"; compilado en modo RELEASE, imprime "Estoy roto". ¿Suena similar? Compruebe que no está llamando a ningún método de depuración directamente con cosas que tienen efectos secundarios. En la mayoría de los casos, se puede solucionar por vía indirecta:

string foo = Foo(); 
Debug.WriteLine(foo); 

Ahora se llama en cualquiera de los modos.

+0

Como dije, no creo que haya ninguna directiva de precompilación, atributos de depuración condicional, etc. en nuestro código. Lo mismo ocurre con Debug.WriteLine. Pero se necesita más investigación. –

4

Puede intentar y desactivar Optimize Code en Build Settings. ¿Cuál es el error real que está recibiendo?

Otra cosa que puede hacer es compilar en modo de lanzamiento, pero habilite el #Debug condicional. Esto manejará el caso si usa Diagnostics.Debug y el código afecta su aplicación.

4
Debug.Assert(ImportantMethod()); 
+0

Otro ejemplo muy bueno [Conditional (...)]. –

3

Podría ser una especie de condición de carrera que tiene, si no está trabajando con un código de un solo subproceso. Por ejemplo, si alguna parte de su programa necesita realizar algunas acciones antes de que otras partes puedan acceder a ella, puede fallar en el modo de lanzamiento simplemente porque el código se accede demasiado pronto. Una vez tuvimos un problema similar con un código para teléfonos móviles que funcionaba bien en el emulador, pero en el teléfono, que era más lento, la situación no era la misma.

4

¿Ha intentado incluir los archivos de depuración?(los pdbs)

Si accedes a la configuración de tu proyecto y luego compilas 'tab', selecciona tu versión de lanzamiento en el menú desplegable cerca de la parte superior, luego elige opciones avanzadas de compilación cerca de la parte inferior, asegúrate de configurarlo para crear FULL depurar información, luego volver a desplegar, ahora debería obtener información más detallada sobre el motivo del bloqueo.

4

He visto el tiempo que causa problemas entre la compilación Debug y Release. En general, la compilación de depuración se ejecuta más lentamente que la versión de lanzamiento. Es posible que desee verificar la sección de tiempo crítico de su código.

0

Probablemente sepa esto, pero las variables algunas veces se inicializan de forma diferente en las versiones de depuración y liberación. P. ej. Creo que las variables se inician automáticamente en compilaciones de depuración VC6, esto puede ocultar problemas si no inicializó algo. También creo que las matrices de depuración pueden usar bytes centinela en un intento de indicar sobrepasos. Esto también puede conducir a un comportamiento diferente.

+0

Habría +1 si el interlocutor no hubiera indicado que estaban usando el código administrado. 9 veces de cada 10 cuando he tenido un problema como este, ha estado en C++ y fue porque olvidé iniciar algo correctamente en el .ctor. Afortunadamente para mí, ninguno de esos errores ha llegado a la producción. –

0

Tuve un problema similar. Mi situación como esta: Definí algunas funciones de reflexión en una biblioteca de clase A. Luego definí una biblioteca de control de usuario WPF B, que usa las funciones de la biblioteca A. Luego codifiqué una aplicación que usa el control de usuario de la biblioteca B y funciones en la biblioteca A. Cuando utilicé la versión de depuración de la biblioteca B, funciona bien. Pero cuando utilicé la versión de lanzamiento de la biblioteca B, las funciones de reflexión no funcionaron. También definí otras funciones en la biblioteca A. Parece que solo las funciones de reflexión están causando problemas. No puedo entender la razón. Finalmente, abandoné y moví las funciones de reflexión de la biblioteca A a la biblioteca B. Y funcionó.

1

Tuve un problema en un punto con los finalizadores que se apagaban antes de lo esperado, porque no entendía completamente la interacción entre los finalizadores, el recolector de basura, y cuando un objeto local se considera coleccionable (sugerencia: no está en el cierre del corsé del bloque). Si su código usa finalizadores, puede consultar GC.KeepAlive(). En el siguiente bloque:

void MyFunction() 
{ 
    Foo f = new Foo(); 
    SomeFunction(f.SomeProp); 
} 

f se torna idóneo para su finalización antes de SomeFunction() incluso corre! Si el finalizador hace algo como deshacerse de lo que SomeProp reparta, podría tener problemas. Agregar una llamada al GC.KeepAlive(f) después de la llamada al SomeFunction asegura que f no es elegible para la finalización hasta después de la llamada al KeepAlive().

Editar: Después de todo eso, me olvidé de señalar que este problema era mucho más pronunciado cuando se ejecuta en modo Release. No sé si la compilación Debug pone KeepAlives implícitos para los locales al final de la función para el beneficio del depurador, o si la recolección de basura es simplemente menos agresiva, o qué, pero el modo Liberación exacerbó este problema en gran medida en mi caso.

0

¿Has resuelto tu problema?
Tengo el mismo problema que tú.
Si compilo el dll en la depuración, todo funciona bien.
Si compilo en la versión obtengo una excepción de referencia nula.
Pero si incluyo algunas líneas como la de arriba en llamar a algunos métodos, la excepción se ha ido, incluso en modo de lanzamiento:
System.Diagnostics.EventLog.WriteEntry ("blablabla", "blablabla")

la esperanza de que le ayuda.

1

Asegúrese de que la aplicación se basa en el objetivo de plataforma correcto. Esto puede ser un problema, especialmente cuando se trata de proporcionar o consumir archivos DLL.Busque en "Proyecto-> Propiedades" y seleccione la pestaña "Generar". La opción de destino de la plataforma le permitirá seleccionar entre Cualquier CPU (predeterminado), x86 o x64.

+0

En mi situación particular, terminé configurando todos los proyectos para construirlos como x86. – dev1998

1

En primer lugar, perdón por mi inglés. Sé que esta publicación es antigua pero tengo el mismo problema, y ​​me doy cuenta de que en el modo de depuración la compilación está hecha para 32 bit OS, y el modo de lanzamiento es para 64 bit de forma predeterminada. Esto hace que el dll para 32 bits no funcione en la versión. Si va a Propiedades del proyecto -> compilación, puede elegir la arquitectura que desee. Esto funciona para mí Adiós.

0

En mi caso, fue que mi proyecto de consumo de DLL (en VS) tenía configuración x64, pero la solución estaba en cualquier CPU. Por alguna razón, al ejecutar la aplicación esto no se enganchó con mi DLL x64. Configuré la aplicación a una plataforma x64 explícitamente y todo funcionó correctamente.

Cuestiones relacionadas