.net visual-studio debugging hidden-features

Consejos y trucos para el depurador de Visual Studio para.NET



visual-studio debugging (14)

He estado trabajando durante años con el depurador de VS, pero de vez en cuando me encuentro con una característica que nunca antes había notado, y pienso "¡Maldición! ¿Cómo pude haberme perdido eso? ¡Es muy útil!"

[Descargo de responsabilidad: estos consejos funcionan en VS 2005 en un proyecto de C #, no hay garantías para encarnaciones anteriores de VS u otros idiomas]

Mantenga un registro de las instancias de objetos

¿Trabajando con múltiples instancias de una clase dada? ¿Cómo puedes distinguirlos? En los días de programación de recolección de basura previa, fue fácil hacer un seguimiento de las referencias, solo mira la dirección de la memoria. Con .NET, no puedes hacer eso: los objetos pueden moverse. Afortunadamente, la vista de relojes te permite hacer clic con el botón derecho en un reloj y seleccionar "Crear ID de objeto".

vista de relojes http://img403.imageshack.us/img403/461/52518188cq3.jpg

Esto agrega un {1 #}, {2 #} etc. después del valor de la instancia, dando efectivamente a la instancia una etiqueta única. Se parece a esto:

instancia numerada http://img383.imageshack.us/img383/7351/11732685bl8.jpg

La etiqueta se conserva durante la vida de ese objeto.

Valores significativos para las variables observadas

Por defecto, el valor de una variable vigilada es su tipo. Si desea ver sus campos, debe expandirlo, y esto podría llevar mucho tiempo (¡o incluso tiempo de espera!) Si hay muchos campos o hacen algo complicado.

Sin embargo, algunos tipos predefinidos muestran información más significativa:

  • cadenas muestran sus contenidos reales
  • listas y diccionarios muestran que sus elementos cuentan, etc.

información significativa http://img205.imageshack.us/img205/4808/37220487md1.jpg

¿No sería bueno tener eso para mis propios tipos?

Hmm ...

... algún tiempo de calidad con .NET Reflector muestra qué tan fácil se puede lograr con el atributo DebuggerDisplay en mi tipo personalizado:

[System.Diagnostics.DebuggerDisplay("Employee: ''{Name}''")] public class Employee { public string Name { get { ... } } ... }

... volver a ejecutar, y ...

ta da! http://img60.imageshack.us/img60/926/79816018ha1.jpg

Hay mucha más información sobre el tema aquí: MSDN

Rompe todas las excepciones

... incluso los que se manejan en código Lo sé, soy tan n00b por no saber nada de esto desde que nací, pero aquí va de todos modos, tal vez esto ayude a alguien algún día:

Puede obligar a un proceso depurado a interrumpir el modo de depuración cada vez que se lanza una excepción. ¿Alguna vez fuiste a buscar errores en horas para encontrar un código como este?

try { runStrangeContraption(); } catch(Exception ex) { /* TODO: Will handle this error later */ }

Capturar todas las excepciones es realmente útil en estos casos. Esto se puede habilitar desde Debug> Exceptions ... (Ctrl-Alt-E) . Marque las casillas en la columna ''Lanzada'' para cada tipo de excepción que necesite.

Esos fueron algunos momentos que me golpearon la frente. ¿Te importaría compartir el tuyo?


¿Qué hay de establecer el IDE para romper en excepciones cuando se producen, incluso cuando no tenemos ningún conjunto de puntos de depuración.

Depurar -> Excepciones -> Excepciones de tiempo de ejecución del lenguaje de Commmon -> Lanzado

Esto hace que encontrar problemas ocultos de manejo de excepciones sea sencillo. En realidad, esta es una especie de configuración que cada desarrollador debería haber establecido a lo largo del desarrollo, para evitar excepciones espontáneas o incluso manipuladas que se encuentren por debajo.


Algunos de mí

  • Desmarque la opción "Habilitar solo mi código" en Herramientas-> Opciones-> Depuración.
  • Puntos de interrupción condicionales: me salvan la vida casi todos los días
  • Utilice el origen de .NET framework si las cosas se ponen feas

Aquí hay otro buen truco que aprendí:

System.Diagnostics.Debugger.Break()

programatically hace que el depurador rompa en la siguiente instrucción. La parte realmente buena es que esto también funciona para un programa compilado en modo Release , sin información de depuración.


Cree una macro para adjuntar a un proceso y asigne a un atajo de teclado no utilizado. Mucho más rápido que ir: depurar -> adjuntar al proceso -> buscar el proceso en la lista de procesos -> ...


Dos de mí: uno que espero que todos utilicen en todas partes:

Debug.Assert(<condition>, <message>)

el segundo DebuggerHidden:

<DebuggerHidden()> _ Public Sub ReadDocumentProperty(ByVal propertyName As String, ByRef PropVal As Integer, ByVal DefaultVal As Integer) Try Dim prop As Office.DocumentProperty prop = CustomProps.Item(propertyName) PropVal = CType(prop.Value, Integer) Catch PropVal = DefaultVal End Try End Sub

Incluso si tiene configuradas excepciones de depuración, excepciones, ruptura al lanzarse, las excepciones aquí no serán detectadas.


Dos trucos en código:

Me gusta mucho el atributo System.Diagnostics.DebuggerStepThrough ; puede adjuntarlo a una clase, método o propiedad para que VS no ingrese el código de manera predeterminada al depurar. Lo prefiero sobre el atributo DebuggerHidden ya que todavía le permitirá poner puntos de corte en el código ignorado si realmente necesita depurarlo.

Otra llamada (a veces) útil es System.Diagnostics.Debugger.Launch() ; cuando la ejecución llegue, se le presentará el diálogo "seleccionar un depurador" y se iniciará un depurador. Un poco grosero, pero útil, especialmente desagradable para adjuntar a los procesos, como un proceso que se genera por otro y ejecuta inmediatamente el código.


En código no administrado puede establecer "puntos de interrupción de datos". Utilizan los registros de depuración de la CPU para emitir un INT3 y el depurador se detiene en esa instrucción sin sobrecarga durante el tiempo de ejecución (en una versión anterior, el depurador pasó por el programa comprobando la memoria ... ¡despacio!)

Esto es útil si tiene algún daño en una dirección específica (la pila / pila vaiable puede ser destruida).

También AutoExp.dat in ide / packages / debugger se puede personalizar para mostrar sus estructuras de datos.

puntero, mb muestra un volcado hexadecimal en la ventana del reloj http://msdn.microsoft.com/en-us/magazine/dd252945.aspx

¡Yum!


Encontré la ventana de Módulos útil muchas veces. Indica si el depurador ha cargado un dll requerido y qué versión del dll está cargada. También le permite cargar o descargar manualmente un dll.


Herramientas -> Adjuntar al proceso - fácil de olvidar, pero con él puedo depurar el script en las páginas web, el código administrado cargado en otro proceso (piense en un modelo adicional) o incluso el código no administrado. Tenga cuidado al permitir que seleccione automáticamente el tipo de depuración que le interese.

Traza puntos (y otras características de punto de interrupción ... ¡haz clic derecho en el punto de interrupción y diviértete!) - http://blogs.msdn.com/saraford/archive/2008/06/13/did-you-know-you-can-use-tracepoints-to-log-printf-or-console-writeline-info-without-editing-your-code-237.aspx

La ventana inmediata es impresionante.

La depuración remota es muy útil si implementa aplicaciones (y puede llegar a la máquina donde se puede reproducir el problema).

Hay toneladas más Intenta entrar en WinDbg y SoS!


Los saltos condicionales son muy útiles si tiene un código que se repite mucho pero que solo falla bajo un conjunto específico de condiciones, como el código en un bucle, los métodos llamados desde un bucle o los métodos llamados desde múltiples hilos. Coloque la declaración de interrupción en la línea de interés y establezca sus condiciones para que coincida con el caso de error. (Aquí hay un ejemplo rápido).



Siempre me aseguro de establecer la propiedad "Nombre" en los hilos nuevos que creo. De esa manera, cuando estoy depurando puedo identificar más fácilmente diferentes hilos.


.load sos en la ventana Inmediato :)


try { // do something big } catch { // breakpoint set here: throw CantHappenException("something horrible happened that should never happen."); }

¿Cómo ves la excepción que se lanzó originalmente? En una ventana de reloj, ingrese $ exception