Las razones más comunes para los insectos en versión de lanzamiento que no están presentes en el modo de depuración

StackOverflow https://stackoverflow.com/questions/1762088

  •  21-09-2019
  •  | 
  •  

Pregunta

¿Cuáles son las razones típicas para los insectos y el comportamiento anormal del programa que se manifiestan sólo en modo de compilación de liberación, pero que no se producen cuando se encuentra en modo de depuración?

¿Fue útil?

Solución

Muchas veces, en el modo de depuración en C ++ todas las variables se inicializan nula, mientras que el mismo no ocurre en modo de lanzamiento menos que se indique de forma explícita.

Comprobar si las macros de depuración y variables sin inicializar

¿Su programa utiliza roscado, a continuación, la optimización también puede causar algunos problemas en modo de lanzamiento.

También puedes ver para todas las excepciones, por ejemplo, no directamente relacionados con el modo de liberar pero en algún momento que acabamos de pasar por alto algunas excepciones importantes, como el acceso mem violación en VC ++, pero lo mismo puede ser un problema, al menos en otros sistemas operativos como Linux, Solaris. Lo ideal sería que su programa no debe coger las excepciones importantes como el acceso a un puntero NULL.

Otros consejos

Un error común es usar una expresión con efecto secundario dentro de un ASSERT.

Otras diferencias podrían ser:

  • En un lenguaje de recolección de basura, la colector suele ser más agresivo en modo de lanzamiento;
  • Disposición de memoria puede a menudo ser diferente;
  • La memoria puede ser inicializado de manera diferente (por ejemplo, podría haber puesto a cero en modo de depuración, o reutilizado más agresivamente en la liberación);
  • Los locales puede promoverse para registrar valores de liberación, que puede causar problemas con punto flotante valores.

He sido mordido por una serie de errores en el pasado que han estado bien en versiones de depuración, pero caída en generaciones de lanzamiento. Hay muchas causas subyacentes (incluyendo, por supuesto, los que ya se han resumido en este hilo) y me han sido atrapados por todo lo siguiente:

  • Las variables de miembro o funciones miembro de una #ifdef _DEBUG, de manera que una clase tiene un tamaño diferente en una versión de depuración. A veces #ifndef NDEBUG se utiliza en una versión de lanzamiento
  • Del mismo modo, hay una #ifdef diferente que pasa a ser sólo está presente en uno de los dos construye
  • La versión de depuración utiliza versiones de depuración de las bibliotecas del sistema, especialmente las funciones de montón y de asignación de memoria
  • funciones inline en una versión de lanzamiento
  • Orden de inclusión de archivos de cabecera. Esto no debería causar problemas, pero si usted tiene algo así como un #pragma pack que no ha sido restablecer entonces esto puede conducir a problemas desagradables. Problemas similares también se pueden producir utilizando encabezados precompilados y obligado incluye
  • Cachés: es posible que tenga un código como cachés que sólo se acostumbra en las versiones de lanzamiento, o los límites de tamaño de caché que son diferentes
  • configuraciones del proyecto: las configuraciones de depuración y liberación pueden tener diferentes configuraciones de generación (esto es probable que suceda cuando se utiliza un IDE)
  • Las condiciones de carrera, problemas de tiempo y los efectos secundarios VARIAS, que ocurre como resultado de la depuración único código

Algunos consejos que he acumulado a lo largo de los años para llegar a la parte inferior de depuración insectos / liberación:

  • Intente reproducir el comportamiento anómalo en una depuración construir si se puede, y mejor aún, escribir una prueba unitaria para capturarlo
  • Piense en lo que se diferencia entre los dos: configuración del compilador, cachés, depuración de sólo código. Trate de minimizar las diferencias temporalmente
  • Crear una versión de lanzamiento con optimizaciones apagado (por lo que tiene mayor probabilidad de obtener datos útiles en el depurador), o un optimizada versión de depuración. Al reducir al mínimo los cambios entre depuración y liberación, es más probable que sea capaz de establecer que la diferencia está causando el error.

Sí !, si usted tiene la compilación condicional, puede haber errores de sincronización (optimizado código de liberación verso, no optimizado código de depuración), memoria reutilización vs montón de depuración.

Es posible, especialmente si se encuentra en el ámbito C.

Una de las causas podría ser que la versión de depuración puede agregar código para comprobar si hay punteros callejeros y de alguna manera proteger el código de estrellarse (o comportarse de forma incorrecta). Si este es el caso se debe comprobar cuidadosamente las advertencias y otros mensajes que recibe de su compilador.

Otra causa podría ser la optimización (que está normalmente en para las versiones de liberación y fuera de depuración). El diseño de código y los datos pueden haber sido optimizados y mientras que su programa de depuración simplemente fue, por ejemplo, el acceso a la memoria no utilizada, la versión de lanzamiento está tratando de acceder a la memoria reservada o incluso apuntando a codificar!

Edit: Veo otra que se menciona: por supuesto, es posible que tenga secciones de código enteros que están excluidos de forma condicional si no compilar en modo de depuración. Si ese es el caso, espero que es realmente la depuración del código y no es algo vital para la corrección del programa en sí!

Las funciones de biblioteca CRT se comportan de manera diferente en depuración vs liberación (/ MD vs / MDD).

Por ejemplo, las versiones de depuración menudo pre-rellenar los tampones se pasan a la longitud indicada para verificar su reclamo. Los ejemplos incluyen strcpy_s, StringCchCopy, etc. Incluso si las cadenas terminan antes, el szDest mejor que sea n bytes de longitud!

Por supuesto, por ejemplo, si se utiliza como construcciones

#if DEBUG

//some code

#endif

En .NET, incluso si usted no utiliza la compilación condicional como #if DEBUG, el compilador es todavía mucho más liberal con optimizaciones en modo de lanzamiento de lo que está en el modo de depuración, que puede conducir a liberar sólo los errores también.

Se necesitaría para dar mucha más información, pero sí, es posible. Depende de lo que su versión de depuración. Usted también puede tener la tala o cheques adicionales en que eso no se deje compilados en una versión de lanzamiento. Estos sólo las rutas de código de depuración pueden tener efectos secundarios no deseados que cambian de estado o las variables afectan de manera extraña. Versiones de depuración que generalmente se ejecuta más lento, por lo que esto puede afectar a las condiciones de carrera de roscado y esconderse. Lo mismo para optimizaciones recta hacia adelante desde una compilación de liberación, es posible (aunque poco probable en estos días) que una compilación de liberación puede causar un corto circuito de algo como una optimización.

Sin más detalles, asumiré que "no está bien" significa que, o bien no se compila o tiros algún tipo de error en tiempo de ejecución. Compruebe si tiene código que se basa en la versión de compilación, ya sea a través de declaraciones #if DEBUG o por medio de métodos marcados con el atributo Conditional.

Esto es posible, si usted tiene la compilación condicional para que el código de depuración y liberación de código son diferentes, y hay un error en el código que se utiliza sólo en el modo de lanzamiento.

Aparte de eso, no es posible. Hay diferencia en cómo se compilan depurar el código y el código de liberación, y las diferencias en cómo se ejecuta el código si se ejecuta bajo un depurador o no, pero si alguna de esas diferencias hacen que no sea una diferencia de rendimiento nada, el problema estaba ahí todo el tiempo.

En la versión de depuración del error no puede ser ocurriendo (porque el momento o la asignación de memoria es diferente), pero eso no quiere decir que el error no está allí. También puede haber otros factores que no están relacionados con el modo de depuración que cambia la sincronización del código, haciendo que el error que se produzca o no, pero todo se reduce al hecho de que si el código es correcto, no se produce el error en cualquiera de las situaciones.

Así que no, la versión de depuración no está bien sólo porque se puede ejecutar sin conseguir un error. Si se produce un error cuando se ejecuta en modo de lanzamiento, no es debido a la liberación modo, es porque el error estaba allí desde el principio.

Hay optimizaciones del compilador que puede romper código válido porque son demasiado agresivos.

Trate de compilar el código con menos optimización activada.

En una función no nula, todas las rutas de ejecución deben terminar con una instrucción de retorno.

En el modo de depuración, si se olvida de poner fin a una trayectoria de este tipo con una sentencia return entonces la función retorna generalmente 0 por defecto.

Sin embargo, en modo de lanzamiento de su función puede devolver los valores de basura, lo que puede afectar la forma en se ejecuta el programa.

Es posible. Si esto sucede y no hay compilación condicional está involucrado, lo que puede estar bastante seguro de que su programa está mal, y está trabajando en modo de depuración sólo debido a las inicializaciones de memoria fortuitos o incluso la disposición en la memoria!

Me acaba de experimentar que cuando estaba llamando a una función de montaje que no restaura los valores de los registros anteriores.

En la configuración "Release", VS estaba compilando con / O2 que optimiza el código para la velocidad. Así, algunas de las variables locales, donde simplemente correlacionando con registros de la CPU (para la optimización), que fueron compartidos con la función antes mencionada conduce a daños en la memoria seria.

En cualquier caso si usted no está indirectamente jugar con registros de la CPU en cualquier lugar en el código.

Recuerdo tiempo atrás, cuando estábamos construyendo DLL y PDB en C / C ++.

Me acuerdo de esto:

  • La adición de los datos de registro que alguna vez el error de movimiento o desaparecer o hacer que aparezca un totalmente otro error (lo que no era realmente una opción).
  • Muchos de estos errores donde debido a carbonizan la asignación de strcpy y strcat y arrays de char [], etc ...
  • escardado alguna a cabo mediante la ejecución de los límites corrector y simplemente fijar el cuestiones alloc / dealloc memoria.
  • Muchas veces, fuimos sistemáticamente a través del código y una asignación fija char (al igual que a través de todos los archivos).
  • Definitivamente es algo relacionado con la asignación de memoria y la gestión y las limitaciones y diferencias entre el modo de depuración y modo de lanzamiento.

Y entonces esperaba lo mejor.

A veces, entregado temporalmente versiones de depuración de las DLL a los clientes, a fin de no demorar la producción, mientras se trabaja en estos insectos.

Otra de las razones podría ser llamadas DB. ¿Está ahorrando y actualizando mismo registro varias veces en el mismo hilo, a veces durante la actualización. Su posible error en la actualización o no ha funcionado como se esperaba debido a que el comando create anterior todavía estaba procesando y para la actualización, la llamada db no pudo encontrar ningún registro. esto suele suceder en la depuración como depurador se asegura de completar todas las tareas pendientes antes de aterrizar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top