2009-09-07 6 views
15

Muchas veces trabajo con código optimizado (a veces incluso involucrando bucles vectorizados), que contienen errores y tal. ¿Cómo se podría depurar dicho código? Estoy buscando cualquier tipo de herramientas o técnicas. Uso las siguientes herramientas (posiblemente anticuadas), así que estoy buscando una actualización.¿Cuáles son las formas eficientes de depurar un programa C/C++ optimizado?

utilizo el siguiente:

  • ya que con ddd, no se puede ver el código, yo uso GDB + comando dissambler y veo el código producido; Realmente no puedo pasar por el programa usando esto.
  • ndisasm

Gracias

+0

No es tremendamente perspicaz, pero MSDN tiene un artículo sobre la depuración del código optimizado (al menos en el mundo de Windows): http://msdn.microsoft.com/en-us/library/606cbtzs.aspx. – reuben

+0

no sé si nuestro código es multiplattform, pero al usar Visual Studio, puede depurar un programa optimizado para el compilador, así como la versión de depuración. Paso por el código, los puntos de freno, la ventana de observación, etc. –

+0

Ejecutando en OS de Unix solamente – vehomzzz

Respuesta

19

siempre es más difícil de depurar programas optimizados, pero siempre hay maneras. Algunos consejos adicionales:

  • Realice una compilación de depuración y vea si obtiene el mismo error en una compilación de depuración. No hay punto para depurar una versión optimizada si no es necesario.
  • Utilice valgrind si está en una plataforma que lo admita. Los errores que ves pueden ser más difíciles de entender, pero detectar el problema temprano a menudo simplifica la depuración.
  • La depuración de printf es primitiva, pero a veces es la forma más simple si tiene un problema complejo que solo aparece en compilaciones optimizadas.
  • Si sospecha que hay un problema de tiempo (especialmente en un programa multiproceso), despliegue su propia versión de assert que aborta o imprime si se infringe la condición, y úselo en algunos lugares seleccionados para descartar posibles problemas.
  • Vea si puede reproducir el problema sin usar -fomit-frame-pointers, ya que eso hace que el código sea muy difícil de depurar, y con -O2 o -O3 habilitado. Eso podría darle suficiente información para encontrar la causa de su problema.
  • Aísle partes de su código, construya un banco de pruebas y vea si puede identificar cualquier banco de pruebas que falle. Es mucho más fácil depurar una función que todo el programa.
  • Intente desactivar las optimizaciones una por una con las opciones -fno-X. Esto podría ayudarlo a encontrar problemas comunes, como problemas estrictos de aliasing.
  • Active más advertencias del compilador. Algunas cosas, como los problemas de alias estrictos, pueden generar advertencias de compilación si crean una diferencia en el comportamiento entre diferentes niveles de optimización.
+2

El error con la depuración de printf es que puede enmascarar errores de optimización ya que el código para pasar datos a la llamada printf puede evitar que el código misma optimización. (Y he tenido muchas instancias en las que el código de depuración funciona y optimizado no resultan ser errores del optimizador. OTOH, printf lo ayudará a encontrar errores del optimizador y es una pista de que debe sumergirse en el ensamblado para determinar si tiene un error del optimizador. – jmucchiello

+0

+1 para sugerir construcciones de depuración y valgrind - suponiendo que no ha tropezado con un error del compilador, la única razón por la que una compilación optimizada fallará cuando una compilación de depuración no lo hará es que está pisoteando una parte diferente (y más importante) de la memoria – kdgregory

1

Siempre es más fácil depurar una versión no optimizada, por supuesto. De lo contrario, el desmontaje del código puede ser útil. Otras tecnologías que he usado incluyen la optimización parcial del código forzando la impresión o registro de resultados intermedios, o el cambio de una variable crítica a "volátil", así que al menos puedo mirar ese valor en el depurador.

6

Al depurar compilaciones de lanzamiento, puede poner __asm ​​nops; como marcador de posición para puntos de interrupción (int 3). Esto es bueno, ya que puede garantizar ubicaciones de punto de interrupción sin estropear las optimizaciones del compilador o escribir las instrucciones printf/cout.

+1

No conozco GCC, pero tener un bloque de ensamblaje en línea en MSVC puede afectar la optimización: "algunas otras optimizaciones de toda la función se verán afectadas por la inclusión del lenguaje ensamblador en un función "- http://msdn.microsoft.com/en-us/library/5hd5ywk0.aspx –

0

Lo que usted llama código optimizado está codificado para afeitar ciclos (lo que hace que la depuración sea difícil) pero realmente no está muy optimizado.Here is an example of what I mean.

Desactivaría la optimización del compilador, la depuraría y sintonizaría usted mismo, y luego volvería a activar la optimización del compilador si el código tiene puntos de acceso realmente codificados por el compilador (no en bibliotecas externas). (Defino un punto de acceso como parte del código donde a menudo se encuentra la PC. Eso exime automáticamente los bucles que contienen llamadas de función porque roban la PC.)

Cuestiones relacionadas