2008-12-14 21 views
9

Últimamente he estado depurando bastante las aplicaciones administradas con Visual Studio y WinDbg, y como tal a menudo me piden que ayude a mis colegas en situaciones de depuración. En varias ocasiones he encontrado personas que simplemente insertan puntos de quiebre aquí y allá y esperan lo mejor. En mi experiencia, rara vez es una técnica útil.Mejores prácticas para la depuración

Mi enfoque es algo como esto.

  • Reproduce el problema. Lo ideal sería reducir la entrada tanto como sea posible.

  • Examine lo que no funciona y enumere las teorías sobre dónde puede estar el error.

  • Examine una teoría a la vez depurando esa área específica del código.

Repita los pasos según sea necesario.

Para problemas complejos de depuración, a menudo trabajo con un colega. Para WinDbg esto es especialmente útil.

¿Algún otro consejo útil o mejores prácticas para la depuración?

Respuesta

10

Una de las mejores prácticas es no sumergirse en el depurador de inmediato, pero mire el código y piénselo bien durante un tiempo.

+1

Buen punto - y estoy completamente de acuerdo. Estoy tratando de recoger buenos puntos sobre cómo evitar que las personas entren en un punto de corte/paso único a través de cada línea de modo de código. –

5

Como dice otro cartel, con algunas reflexiones, a menudo es posible ver el error de lógica si entiendes lo que está pasando.

Pero a menudo creemos que sí y no, o simplemente nos piden que corrijamos algo que no entendemos muy bien, por lo tanto, volvemos a los principios básicos.

La reproducción del problema es ciertamente un primer paso vital. Si no puedes hacer esto, entonces no tienes ninguna posibilidad de encontrar el problema, excepto por accidente.

El siguiente paso es establecer sin lugar a dudas la ruta a través del código que realmente se ejecuta cuando se produce el error. En una aplicación WinForms que podría tener muchos eventos y más de un hilo, esto puede ser cualquier cosa menos un ejercicio trivial.

Hasta que sepa exactamente a dónde va el código, todas las teorías del mundo sobre dónde puede estar el error no tienen valor. Y si el código es complejo, descubrir que el código no se detiene en un punto de interrupción puede ser tan informativo como detenerlo.

Por lo tanto, en mi experiencia, el uso temprano de los puntos de interrupción ya menudo puede ser una herramienta esencial para descubrir cómo funciona un código.

A menudo me parece que cuando un problema parece particularmente intratable, es porque he asumido fatalmente lo que está sucediendo y no lo he verificado.

Así que mi "mejor práctica" es no seguir adelante hasta que esté seguro de entender, y no adivinar.

3

Las barreras de entrada para el depurador en VS.NET con un lenguaje como C# o VB.NET son tan ridículamente bajas que a menudo es más fácil insertar un punto de interrupción o dos donde sabes que el problema es y simplemente atravesarlo .

veces me encuentro con Edición & Continuar a escribir código. Es genial. Puedes ver resultados de inmediato. A menudo es más útil cuando hay algún algoritmo o lazo relativamente difícil de entender.

11

Si hubiera un consejo que podría darles a todos acerca de la depuración, sería romperlo de nuevo.

Es decir, cuando se piensa que ha encontrado la solución y el sistema parece funcionar. Retroceda la reparación y vea si el sistema se rompe nuevamente.

A veces puede perderse en la secuencia de lo que ha intentado como soluciones potenciales y terminar en un área totalmente diferente del sistema, mientras que va a depurar el problema. Entonces olvidas lo que has cambiado en el área original donde estabas trabajando.

Copia de la solución y luego reproducir el problema asegura que la solución candidata no se basa en algo más que ha cambiado en otra parte del sistema. Que su parche para la solución sea una solución independiente correcta.

HTH.

aplausos,

Rob

4

no directamente relacionados con la depuración, pero para hacer más fácil la depuración en el futuro, hay algunas cosas a considerar:

  • ejecución de pruebas de unidad, de preferencia en la forma de TDD te obliga a mantenerte en tu tarea y desarrollar solo con el objetivo de pasar las pruebas. Es más difícil "vagar" cuando está codificando para una prueba, en lugar de una tarea.
  • Realice la práctica de refactorizar regularmente su código. Los métodos pequeños y puntuales son más fáciles de depurar que los métodos monolíticos de "jack of all trades".
  • Utilice los miembros de su equipo. A menudo, agregar un par de ojos adicionales puede ayudar a eliminar algo. Lo más probable es que, si no encuentra algo de una manera relativamente rápida, vaya a continuar pasándolo por alto durante un tiempo.
  • Siempre puede revertir el código en su sistema de control de versiones para tratar de aislar qué versión de un archivo provocó la introducción del error. Una vez que haces eso, puedes diferenciar entre el último bien y el primer mal y solo enfocarte en los cambios entre los dos.
0

Acabo de reproducir en another post, la pregunta era C la depuración, pero como dije en mi repetición, creo que las técnicas de depuración son independientes del lenguaje.

1

Como Conceptual Blockbusting sugiere, me gusta probar diferentes maneras cada vez que se queda bloqueado. "depuración de printf", pensando en el comportamiento, búsqueda binaria en el código, búsqueda binaria en commit de control de versión, escribiendo una prueba de unidad para aclarar, scratch refactoring, y también activando el depurador.

1

IMO demasiada preparación es una pérdida de tiempo. Si conoces la base de código bastante bien, normalmente siempre puedes pensar en algunos lugares clave donde se manifiesta el problema. Ponga puntos de quiebre allí y vea si tiene razón. Cada vez que veas mejores puntos clave, mueve tus puntos de quiebre para acercarte al problema.

Cuando está persiguiendo datos incorrectos, como un puntero nulo, depende de dónde viene: si se pasa como un argumento, mire la pila de llamadas para ver de dónde viene.Si es parte de alguna estructura de datos u objeto (el caso más fácil), coloque un punto de interrupción allí para ver cuándo y cómo se modifica.

Los puntos de interrupción condicional pueden ser de gran ayuda, de lo contrario, puede simularlos agregando declaraciones if que incluyen no-ops. Si tiene un punto de quiebre en un punto caliente que recibe demasiado a menudo antes de llegar al problema, desactívelo y coloque otro en un lugar que sepa que será golpeado poco antes de que se manifieste el problema, luego active el que está en el punto caliente.

+1

Bueno, nos estamos acercando rápidamente a un millón de líneas de código, por lo que nadie conoce la base de código razonablemente bien en nuestro caso. –

+0

Brian: si nadie en su organización puede limitar un error a unos pocos archivos en la mayoría de los casos, entonces usted tiene problemas mucho más grandes que solo el error. Nadie "confía" en el código y está acumulando deuda técnica. –

1

Una buena práctica es asegurarse de que no está solucionando un síntoma, sino la causa.

A menudo, uno podría ver un valor extraño mientras depura y arreglarlo allí, sin verificar qué causó que el valor llegue allí en primer lugar. Esta es, por supuesto, una muy mala idea.

Por cierto, esta es la razón por la que Linus objetó agregar compatibilidad integrada para la depuración del kernel.

+0

identificando cuando estás viendo un síntoma o una causa es el truco aunque – annakata

0

Una cosa que me gusta recalcar es que cuando tienes una instancia funcionando y otra no (digamos producción y desarrollo) se trata de las diferencias y necesitas identificar claramente cuáles podrían ser y tratar con ellas una en una tiempo. Los problemas ambientales pueden ser los más difíciles de rastrear y te volverás loco si no trabajas sistemáticamente.

Dicho sea de paso, esta es una de las razones por las que habitualmente ejecuto mis proyectos de VSwebapp a través de IIS no cassini.

1

Voy a parafrasear my answer on a similar thread (que es esencialmente el último punto en joseph.ferris's answer to this thread):

Usando el sistema de control de versiones, aislar la revisión de archivos donde se introdujo el error, utilizando el enfoque del árbol de búsqueda binaria.

Diff que la revisión del archivo de origen contra la revisión anterior. La diferencia puede hacer que la razón del error sea evidente.

+0

Me gusta este enfoque y lo uso mucho, excepto que se rompe cuando no sabes cuando apareció el error por primera vez. –

+1

@Gustavo: no necesita saber dónde apareció el error. El algoritmo de búsqueda binaria lo ayudará a encontrar dónde. Por ejemplo, supongamos que su código está en la versión 5.0 y tiene el error. Cree la versión 3.0 y vea si el error está presente. Dependiendo de si 3.0 tiene el error, la próxima versión que cree y pruebe sería 2.0 o 4.0. El sistema de control de versiones Git (http://en.wikipedia.org/wiki/Git_%28software%29) incluso tiene un comando "git bisect" que elige automáticamente las versiones para usted. Solo dile a git si la versión que revisó es buena o mala y git obtiene la próxima versión para compilar y probar. – JeffH

2

Este libro es honestamente el mejor que he leído sobre la depuración, especialmente cuando está más allá de la situación normal de depuración. Contiene muchos trucos y es divertido de leer con toda la "historia real". Si trabajas con una gran cantidad de código que no has escrito, especialmente si es malo, ¡este libro es obligatorio!

http://www.amazon.com/Debugging-Applications-Microsoft%C2%AE-Microsoft-Pro-Developer/dp/0735615365/ref=sr_1_1?ie=UTF8&s=books&qid=1238705836&sr=1-1

alt text http://ecx.images-amazon.com/images/I/51RQ146x9VL._SS500_.jpg

+0

Sí, he leído ese libro. Me enseñó algunos trucos. – RichardOD

7

no estoy seguro de que he leído acerca de "Depuración de goma del pato", pero creo que es genial. La idea básica es colocar un pato de goma en su escritorio y explicarle el código. La idea es que mientras explicas el código al pato, eventualmente te encuentres diciendo "Ahora, esto sucede", y notarás que "esto" no es lo que pretendes que ocurra.

A falta de un pato, me parece que paso por el código y me lo explico. Funciona, pero todavía creo que podría traer un pato.

[EDIT] encontré donde leí sobre el pato de goma Rubber Duck Debugging

+0

¡Impresionante! ¡Necesito encontrarme un pato de goma! –

2

algo que ayuda, especialmente cuando eres nuevo en la depuración, es mantener algún tipo de revista de depuración, con soluciones a los problemas que' he resuelto en el pasado.La mayoría de los errores siguen patrones relativamente comunes (por ejemplo, los problemas aparentemente aleatorios en las aplicaciones sin subprocesos generalmente se deben a variables indefinidas, o al uso similar de memoria no inicializada) y al realizar un seguimiento de esos patrones, obtendrá mucho mejor para obtener problemas futuros

Después de un tiempo, que acaba de desarrollar la intuición necesaria (y luego su diario se convierte una muy divertido de todos los enemigos desagradables que ha conquistado)

0

Otra cosa que he empezado a hacer a todos mis proyectos es para agregar un TraceListener (o una clase derivada) y usarlo para tomar instantáneas clave de mi aplicación.

Esto generalmente me da una buena idea de dónde enfocar mis esfuerzos iniciales de depuración.

Además, puedo activar/desactivar el uso de un interruptor de archivo de configuración, por lo que incluso puedo obtener una pista sobre un sistema de producción, sin volver a compilar el código.

1

Esto no es un consejo técnico, pero a menudo funciona en mi caso.

Solo deja de trabajar duro para encontrar una causa raíz o corregir un error. Relájese por un momento: salga a caminar, cene, o simplemente cambie a otra tarea (con suerte, mucho más fácil) - lo que quiera ...

... Luego piense en un problema un poco más tarde, cuando esté "fresco" de nuevo. Haga un seguimiento de todo el proceso mental de depuración que ya ha experimentado (teorías, experimentos, suposiciones, etc. que hizo). Lo más probable es que vea instantáneamente algún factor clave que haya pasado por alto antes;).

Los programadores (o al menos yo) tienden a reducir gradualmente su perspectiva de problema y desgaste de la creatividad durante una sesión de depuración larga. ¡Pero una amplia perspectiva combinada con ideas creativas es el arma más poderosa del hombre en la batalla contra los insectos!

+0

Sé que el truco de ir a caminar me ha funcionado bien. También tengo un juguete de pingüino en mi escritorio, cuando estoy realmente frustrado con un problema trato de explicárselo desde cero, como si fuera otro desarrollador. Sé que suena loco, pero el proceso de explicarle tu problema a alguien/a algo más te obliga a ver el problema como un extraño. Esto a menudo lleva a ideas que normalmente no tendrías por tu cuenta. –