2009-06-01 12 views
7

¿Es posible que el depurador (o el manejador de excepciones CLR) muestre la línea donde ocurrió la excepción en modo Liberación usando el pdb?Obteniendo el número de línea desde pdb en el modo de lanzamiento

El código, en modo de lanzamiento, está optimizado y no siempre sigue el orden y la lógica del código "original".

También es sorprendente que el depurador pueda navegar por mi código paso a paso, incluso en el modo de lanzamiento. La optimización debería hacer que la navegación sea muy incómoda.

¿Podría aclarar esos dos puntos para mí?

Respuesta

10

No estoy tan familiarizado con la forma en que se hace esto con CLR, pero es probablemente muy similar a cómo se hace con el código nativo. Cuando el compilador genera instrucciones de máquina, agrega entradas al pdb que básicamente dicen "la instrucción en la dirección actual, X, vino de la línea 25 en foo.cpp".

El depurador sabe qué dirección de programa se está ejecutando actualmente. Entonces busca una dirección, X, en el pdb y ve que proviene de la línea 25 en foo.cpp. Al usar esto, puede "avanzar" a través de su código fuente.

Este proceso es el mismo independientemente del modo de Depuración o Liberación (siempre que se genere un pdb en modo Liberación). Sin embargo, tiene razón en que, en modo de lanzamiento debido a las optimizaciones, el depurador no pasará "linealmente" a través del código. Podría saltar a diferentes líneas inesperadamente. Esto se debe a que el optimizador cambia el orden de las instrucciones, pero no cambia la asignación de la dirección a la línea de origen, por lo que el depurador aún puede seguirlo.

+0

Ty para su respuesta detallada. Las cosas ahora están claras para mí. –

0

El depurador hace un buen esfuerzo para adivinar dónde ocurrió el problema. No está garantizado que sea 100% preciso, y con un código completamente optimizado, a menudo será impreciso. Encontré que las imprecisiones varían desde unas pocas líneas hasta tener una pila de llamadas completamente incorrecta.

Cuán exacto es el depurador con el código optimizado realmente depende del código en sí y qué optimizaciones está realizando.

+1

Ty. "tener una pila de llamadas completamente incorrecta". ¿El seguimiento de la pila no debe ser siempre exacto? –

+0

¿Hay alguna fuente o más información sobre los números de línea que se activan? He puesto algunas publicaciones en SO sobre depuración/pdb/optimización del código del compilador, y no encontré ningún punto claro sobre esto. – gerleim

1

[@Not Claro] lo tiene casi justo. El compilador hace un mejor esfuerzo para identificar un número de línea apropiado que coincida estrechamente con la instrucción actual de código de máquina.

El PDB y el depurador no saben nada acerca de las optimizaciones; el archivo PDB esencialmente asigna direcciones de direcciones en el código de máquina a números de línea de código fuente. En el código optimizado, no siempre es posible hacer coincidir exactamente una instrucción de ensamblaje con una línea específica de código fuente, por lo que el compilador escribirá en el PDB lo más cercano que tiene a mano. Esto podría ser "la línea de código fuente anterior", o "la línea de código fuente del contexto adjunto (bucle, etc.)" u otra cosa.

Independientemente, el depurador encuentra esencialmente la entrada en el mapa de PDB más cercana (como en "antes o en la igualdad") a la IP actual (Puntero de instrucción) y resalta esa línea.

A veces la coincidencia no es muy buena, y es entonces cuando ve el área resaltada saltando por todos lados.

+1

Quizás el compilador genere un pdb diferente para la versión y para el modo de depuración. El pdb para el modo de lanzamiento toma en consideración la optimización, por lo que puede proporcionar una línea relativamente precisa para una excepción. –

+0

Oh, absolutamente. El PDB está vinculado para siempre a la misma instancia exacta de la DLL (o EXE) con la que se creó. Tenga en cuenta que incluso si vuelve a compilar en el mismo modo, sin ningún cambio en el archivo de origen, todavía no puede mezclar y combinar los PDB y las DLL. Su PDB debe ser exactamente el mismo que se creó cuando se compiló el módulo (DLL o EXE) que está depurando porque el compilador puede colocar cosas al azar en diferentes lugares en cada compilación. ¿Eso era lo que intentabas hacer? –

+0

@Euro Micelli:> el compilador puede colocar cosas al azar en diferentes lugares en cada compilación

Cuestiones relacionadas