¿Debo compilar versiones de lanzamiento con información de depuración como "completa" o "solo pdb"?

114

En Visual Studio 2010 para un proyecto de C #, si va a Propiedades del proyecto> Compilación> Avanzado> Información de depuración, tiene tres opciones: ninguna, completa o solo pdb. Según la respuesta a esta pregunta , creo que entiendo algunas de las diferencias entre full y pdb-only. Sin embargo, ¿cuál es más apropiado para una versión de lanzamiento? Si utilizo "completo", ¿habrá ramificaciones de rendimiento? Si utilizo "solo pdb", ¿será más difícil depurar problemas de producción?

¿Cuál es la diferencia entre "full" y "pdbonly"? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option

RationalGeek
fuente
El pdb-only o none, siempre para versiones de lanzamiento.
leppie
13
@leppie Gracias, pero estoy buscando alguna justificación de esa posición.
RationalGeek
Pregunta relacionada: stackoverflow.com/questions/1270986/…
janv8000
Eso es genial si no hay impacto en el rendimiento. ¿Qué pasa con el impacto de la memoria? Si creo una instancia de StackTrace y solicito información de archivo, tiene que provenir de los datos del símbolo pdb. ¿Se cargan todos los símbolos en la memoria al iniciar la aplicación? ¿Cuál es el uso de memoria aproximado de esto? (por ejemplo, porcentaje de sobrecarga relativa al tamaño del código)
Yoyo

Respuestas:

90

Construiría con pdb-only. No podrá adjuntar un depurador al producto publicado, pero si obtiene un volcado por caída, puede usar Visual Studio o WinDBG para examinar los seguimientos de pila y volcados de memoria en el momento del bloqueo.

Si elige en fulllugar de pdb-only, obtendrá los mismos beneficios, excepto que el ejecutable se puede adjuntar directamente a un depurador. Deberá determinar si esto es razonable dado su producto y clientes.

Asegúrese de guardar los archivos PDB en algún lugar para que pueda hacer referencia a ellos cuando llegue un informe de fallas. Si puede configurar un servidor de símbolos para almacenar esos símbolos de depuración, mucho mejor.

Si opta por construir con none, no tendrá ningún recurso cuando haya un accidente en el campo. No podrá hacer ningún tipo de examen posterior del accidente, lo que podría obstaculizar gravemente su capacidad para localizar el problema.

Una nota sobre el rendimiento:

Tanto John Robbins como Eric Lippert han escrito publicaciones de blog sobre la /debugbandera y ambos indican que esta configuración tiene un impacto cero en el rendimiento . Hay una /optimizebandera separada que dicta si el compilador debe realizar optimizaciones.

Matt Dillard
fuente
7
@ Matt, el artículo de MSDN sobre el modificador / debug advierte explícitamente sobre un impacto en el rendimiento del uso de la configuración 'completa':If you use /debug:full, be aware that there is some impact on the speed and size of JIT optimized code and a small impact on code quality with /debug:full. We recommend /debug:pdbonly or no PDB for generating release code.
Allon Guralnek
3
@Matt: Si 'full' no tiene desventajas en comparación con 'pdb-only', pero solo tiene ventajas, ¿por qué existe 'pdb-only'? ¿Hay alguna razón para usarlo en exceso? Además, debe agregar la corrección al artículo de MSDN en la sección 'Contenido de la comunidad'.
Allon Guralnek
9
@AllonGuralnek cita del artículo vinculado de John Robbins: La verdadera razón: la historia. En .NET 1.0 había diferencias, pero en .NET 2.0 no las hay. Parece que .NET 4.0 seguirá el mismo patrón. Después de verificar dos veces con el equipo de depuración de CLR, no hay ninguna diferencia.
bentayloruk
5
Eso no es cierto. Puede compilar solo con pdb y aún así adjuntar un depurador. Solo lo hice para estar seguro.
Mark
2
"Construiría solo con pdb. No podrá adjuntar un depurador al producto publicado" ¿Cuál es su fuente de información aquí? Como hemos señalado tanto @Mark como yo, esto no parece ser correcto.
MEMark
66

ADVERTENCIA La documentación de MSDN para el modificador / debug (en Visual Studio es Información de depuración) parece estar desactualizada. Esto es lo que tiene que es incorrecto

Si usa / debug: full , tenga en cuenta que hay cierto impacto en la velocidad y el tamaño del código optimizado JIT y un pequeño impacto en la calidad del código con / debug: full . Recomendamos / debug: pdbonly o no PDB para generar código de lanzamiento.

Una diferencia entre / debug: pdbonly y / debug: full es que con / debug: full el compilador emite un DebuggableAttribute, que se usa para decirle al compilador JIT que hay información de depuración disponible.

Entonces, ¿qué es verdad ahora?

  1. Solo Pdb : antes de .NET 2.0, ayudaba a investigar los volcados por caída del producto lanzado (máquinas del cliente). Pero no permitió adjuntar el depurador. Este no es el caso de .NET 2.0. Es exactamente igual que Full .
  2. Completo : esto nos ayuda a investigar los volcados por caída y también nos permite adjuntar el depurador a la versión de lanzamiento. Pero a diferencia de las menciones de MSDN, no afecta el rendimiento (desde .NET 2.0). Hace exactamente lo mismo que solo Pdb .

Si son exactamente iguales, ¿por qué tenemos estas opciones? John Robbins (dios de la depuración de Windows) descubrió que estos están ahí por razones históricas.

En .NET 1.0 había diferencias, pero en .NET 2.0 no las hay. Parece que .NET 4.0 seguirá el mismo patrón. Después de verificar dos veces con el equipo de depuración de CLR, no hay ninguna diferencia.

Lo que controla si JITter realiza una compilación de depuración es el conmutador / optimizar. <…>

La conclusión es que desea crear sus versiones de lanzamiento con / optimizar + y cualquiera de los modificadores / debug para que pueda depurar con el código fuente.

luego pasa a demostrarlo.

Ahora la optimización es parte de un cambio separado /optimize(en Visual Studio se llama Optimize code).

En resumen, independientemente de la configuración de DebugInfo como pdb-only o full, obtendremos los mismos resultados. La recomendación es evitar Ninguno, ya que le privaría de poder analizar los volcados por caída del producto lanzado o adjuntar el depurador.

rpattabi
fuente
3
¡Respuesta fantástica! Mis propias investigaciones (comparando archivos generados) muestran los mismos resultados.
MEMark
@rpattabi ¿Puede especificar la referencia de que pdbonly y full son lo mismo? Es 2019 y la documentación aún indica que son diferentes y que tendrán una degradación del rendimiento. Y VS2019 crea un proyecto con Releaseel tipo de depuración de configuración predeterminado en pdbonly.
joe
@joe Hay una discusión al final de la documentación de MSDN msdn.microsoft.com/en-us/library/8cw0bt21.aspx . Mira esto. Un colaborador señaló github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/… para obtener información actualizada donde pdbonly y full se mencionan como lo mismo. (Para su información. Ya no uso Windows ni VS. Por lo tanto, no he estado siguiendo lo que está sucediendo allí. Pero, como revisé, la información en mi respuesta sigue siendo relevante y el documento de MSDN sigue siendo incorrecto).
rpattabi
16

Solo querrá PDB, pero no querrá dar los archivos PDB a los usuarios. Sin embargo, tenerlos para usted, junto con sus binarios, le brinda la capacidad de cargar volcados de emergencia en un depurador como WinDbg y ver dónde falló realmente su programa. Esto puede ser bastante útil cuando su código falla en una máquina a la que no tiene acceso.

La depuración completa agrega el atributo [Debuggable] a su código. Esto tiene un gran impacto en la velocidad. Por ejemplo, algunas optimizaciones de bucle pueden deshabilitarse para facilitar el paso único. Además, tiene un pequeño efecto en el proceso JIT, ya que activa el seguimiento.

soplar el dardo
fuente
Tiene sentido. Realmente no distribuyo archivos DLL a los usuarios de todos modos, es una aplicación ASP.NET. Pero, ¿puede mejorar su respuesta y justificar por qué debería elegir "solo pdb" frente a "completo"? ¿Es un problema de rendimiento?
RationalGeek
@jkohlhepp: me gustaría agregar que depurar las versiones de lanzamiento es un poco complicado ya que perderá algo de información (debido a JIT). Casi siempre, no podrá ver los valores de los argumentos del método. Para solucionar esto, puede deshabilitar temporalmente la optimización JIT usando esto .
Ilian Pinzon
Gracias, blowdart, y gracias a Ilian Pinzon por la información adicional. Sé que no se puede obtener una depuración perfecta con el código de lanzamiento, pero tener los PDB es mejor que nada.
RationalGeek
El uso de la configuración "completa" no tiene un impacto en el rendimiento. Simplemente permite adjuntar un depurador a un proceso en ejecución.
Matt Dillard
1
Buena pregunta sobre MSDN Matt, msdn.microsoft.com/en-us/library/8cw0bt21 , esperando la respuesta yo mismo.
Luke Hutton
4

Estoy en el proceso de escribir un controlador de excepciones no controlado y el seguimiento de la pila incluye el número de línea cuando se usa solo pdb; de lo contrario, obtengo el nombre de la Sub / Función cuando elijo Ninguno.

Si no distribuyo el .pdb, no obtengo el número de línea en el seguimiento de la pila, incluso con la compilación de solo pdb.

Entonces, estoy distribuyendo (implementación de XCOPY en una LAN) el pdb junto con el exe de mi aplicación VB.

rheitzman
fuente