debugging - homepage - ¿Hay algún patrón de depuración?
webpack version (16)
Añadiré un patrón de depuración más que parece bastante obvio, pero aún no se ha dicho:
Reduce el error al caso más pequeño posible, y luego usa eso como tu unidad de prueba para cualquier solución propuesta.
Sé que hay muchos patrones de diseño populares y útiles.
¿Hay algo así como ellos para depurar escenarios? Tal vez no patrones sino metodologías que están categorizadas y que pueden usarse repetidamente para casos similares.
Aquí hay algunos que funcionan para mí:
- Aléjate del problema. De manera similar a "dormir más", a veces alejarse del problema y centrarse en algo completamente diferente (por ejemplo, salir a trabajar) ayuda a proporcionar claridad cuando se reanuda el trabajo sobre el problema.
- Explica el problema a mi esposa. Bueno, no tiene que ser mi esposa específicamente, sino alguien que no está familiarizado con el problema, el sistema ni nada. Esto lo forzará a tener que sacar suposiciones a la superficie, explicar cómo funciona realmente el sistema, tal vez incluso volver al código para verificar lo que está diciendo. A menudo he tenido avances significativos después de este tipo de intercambio.
Cuando estoy filmando en la depuración oscura, tomo el enfoque de búsqueda binaria. Comenta la mitad de mi código o la mitad de un método, algo así, luego me concentro en la mitad sin comentar. Si el problema aún existe, comento otra mitad. Y así.
Especializando esto para la depuración del sombreador de fragmentos OpenGL, que es muy opaco. Hacer las tonterías es bueno y necesario, pero verificar el resultado es más complicado que la programación de la aplicación regular, por lo que necesita algunos trucos:
- Renderice diferentes partes en r, g, b, usando step () si necesita verificar cambios de valores precisos. (Bueno para detectar errores de punto flotante como 1.001 o -0.001)
- Aprenda a interpretar rgb como un vector xyz normalizado.
- Elimine las muestras de textura, trace las coordenadas de textura como colores.
- Considere representar diferentes variables en diferentes partes de la pantalla y tener una cámara flotante.
Esta no es realmente una técnica de depuración, pero creo que tenemos que mencionar una condición previa de depuración que, si no se cumple, complicará mucho su trabajo.
Realmente no se puede iniciar una depuración significativa hasta que el error sea reproducible, con una receta paso a paso. Si obtiene un informe de error grave, puede terminar teniendo que discernir esa receta usted mismo, pero si está apoyando a alguien, debe hacerles saber que descubrir la receta llevará más tiempo que hacerlo por usted e incluso puede ser imposible. Un informe de error útil tiene que responder a las tres preguntas de lo que llamo la fórmula de informe de error: 1) ¿qué hiciste? 2) ¿Qué esperabas que sucediera? 3) qué pasó en su lugar?
Por supuesto, algunos errores son Heisenbugs, aparentemente transitorios. Debería tratar de obtener algo parecido a una afirmación como "Si hago lo siguiente, parece que aproximadamente el 10% de las veces ocurre este resultado indeseable".
Una vez que tenga la receta, el siguiente paso a menudo se reduce a un caso de prueba mínimo, como han mencionado otros.
Estoy de acuerdo con los demás sobre las Pruebas Unitarias como un "Patrón" para prevenir errores. adicionalmente me gustaría citar los siguientes pasos de Debugging: Las 9 reglas indispensables para encontrar incluso los problemas más difíciles de software y hardware :
- Comprenda el sistema
- Hacer que falle
- Deja de pensar y mirar
- Divide y conquistaras
- Cambiar una cosa a la vez
- Mantenga una pista de auditoría
- Comprueba el enchufe
- Obtenga una vista fresca
- Si no lo solucionaste, no está arreglado
Y por último, en el aspecto más práctico, Dimitry Vostokov ha reunido algunos patrones de depuración muy agradables en su libro y sitio web .
Hay algunos patrones más formales para eliminar errores específicos:
- Eliminar el patrón de ruido
- Patrón de error recurrente
- Patrón de error específico del tiempo
Sin embargo, creo que la mayoría de sus decisiones de depuración y flujo de trabajo van a estar ya diseñados por el entorno que usa.
La forma en que depuro es la forma en que resuelvo los problemas. Yo uso el método cartesiano .
Hay 4 reglas :
- No aceptar nada como verdadero que la razón no reconozca como claro y distinto;
- Analizar ideas complejas desglosándolas en sus elementos constitutivos simples, que la razón puede intuir intuitivamente;
- Para reconstruir, comenzando con ideas simples y trabajando sintéticamente para el complejo;
- Para hacer una enumeración precisa y completa de los datos del problema, utilice en este paso los métodos de inducción y deducción.
O, di de manera diferente :
- Acepta como verdadero solo lo que es indudable.
- Divida cada pregunta en partes manejables.
- Comience con los problemas más simples y ascienda a los más complejos.
- Revise con suficiente frecuencia para retener todo el argumento a la vez.
Solo tiene que adaptar estas reglas en el contexto de la programación.
Si tuviera que reanudar, diría que tomar el problema / error es una expresión simple. Hazlo iterativamente
Me gusta pensar que Unit Testing es un patrón de depuración. Si puede reproducir el problema, puede escribir una prueba unitaria para que sea mucho más fácil de depurar.
Una vez que tenga la prueba de unidad de "nivel superior" que utiliza para resolver el problema, siempre puede crear más pruebas de unidades defectuosas en niveles más bajos y más bajos en su código para ayudarlo a enfocarse en el error al agregar pruebas unitarias que serán útil a largo plazo en su proyecto.
Mi enfoque es usar el método científico:
- Reunir datos sobre lo que está sucediendo, probar muchas entradas diferentes y ver qué resultados obtengo
- Desarrollar una hipótesis sobre lo que está sucediendo
- Pruebe dicha hipótesis, y no estoy en lo cierto, luego regrese al paso 1 y repita.
Otros (Xynth, Broam, Moshe) han mencionado la necesidad de obtener un caso de prueba mínimo, con suerte uno que se pueda insertar en el conjunto de pruebas de la unidad. Estoy de acuerdo. Una vez que pueda hacer que ocurra el error, comience a quitar factores adicionales, o incluso código (como sugirió Bob), probando en cada paso para ver si el error desapareció. Si está en cron, ejecútelo manualmente. Si se ejecuta desde la GUI, pruébelo desde una línea de comandos o un conjunto de pruebas simple.
Si tiene problemas, el enfoque opuesto suele ser útil: cree un programa pequeño y minimalista que haga un par de cosas que hace la rutina de errores. Pruébalo y ve si tienes el error. Luego, paso a paso, intente escribir un programa de trabajo que haga lo que se supone que debe hacer la rutina con errores. En algún momento, puede ver el error exhibido, en cuyo caso ahora tiene su caso de prueba. O bien, puede llegar a una rutina exitosa. En este caso, comience a transformar esa rutina, línea por línea, en una réplica exacta de su código, haciendo pruebas en el camino para ver cuándo aparece el error.
Si tiene un código que solía funcionar y ahora muestra un error y un historial de versión completo, una búsqueda binaria a través de su historial puede ser muy útil. Eliges un punto a medio camino entre la confirmación de trabajo y no trabajo, y compilas y pruebas. Si esa confirmación muestra el error, usted sabe que comenzó aquí o antes, por lo que regresa a medio camino entre aquí y el compromiso confirmado y prueba nuevamente; de lo contrario, sabrá que el error comenzó más tarde, por lo que puede avanzar a medio camino entre aquí y el compromiso malo conocido, y probar allí. Sigues este proceso hasta que descubres qué cometido introdujo el error, y luego ves lo que cambió, y hay una buena posibilidad de que el problema sea obvio.
git bisect es una herramienta espectacular para este propósito. Pero teóricamente podrías hacer lo mismo con un montón de archivos comprimidos, si eso es todo lo que tienes.
Por supuesto, esto no funcionará si el error ha estado dentro y fuera del árbol varias veces. Y probablemente no será muy útil si tus compromisos no son muy finos.
Solo algunos que he encontrado:
- Cuando dos sistemas idénticos generan resultados diferentes, verifique (en orden de probabilidad):
- Las versiones de todos los componentes son, de hecho, idénticas entre los dos sistemas,
- La configuración es idéntica entre los dos sistemas, y
- No hay datos residuales en un sistema que no estaba presente en el otro.
- gdb y gcc analizan el código mejor que yo. Deje que el software haga su trabajo para que pueda hacer el suyo.
- Cuando los datos salgan en un extremo de un proceso diferente al que está esperando, verifique los datos a lo largo del proceso para verificar que es el esperado, en lugar de centrarse en una función en el proceso posterior al problema real.
- No se centre en una pieza específica de código si no ha verificado que es la causa del error.
- Dormir mas. La depuración de alertas siempre es más efectiva.
Tengo más en mi sitio web en Desarrollo de software -> Depuración si está interesado.
El aislamiento de fallas es uno. ¿El problema ocurre en todos los sistemas operativos, o está relacionado solo con un sistema operativo?
Proceda por dicotomía para determinar la ubicación y la causa del problema.
Gracias por todas las ideas Fueron realmente útiles. Por lo que yo entiendo, no hay una cierta lista de patrones como los patrones de diseño cuando se trata de corregir errores. Tal vez después de algún momento todos tengan su propio camino.
Uno de los enfoques que uso es, si el proceso parece complicado, sentarme y tratar de ver si puedo volver a factorizar el código. Esto me da la oportunidad de refrescar mi mente sobre el comportamiento del código, tener una mejor comprensión y hacer que sea incluso más fácil de mantener. El método de extracción es mi favorito para tener unidades lógicas legibles.
Una de mis cosas favoritas es que si se cambia el valor de una propiedad de manera inesperada, pongo un punto de ruptura en el establecimiento de esa propiedad. No sé si es posible hacerlo con desaceleraciones de propiedad implícitas (bool myProperty {get; set;}).
Tal vez sería mejor comenzar con un catálogo BUG que muestre todos los tipos de errores categorizados con descripciones.
gracias, burak ozdogan
Dmitry Vostokov ha estado catalogando muchos patrones de depuración en http://www.dumpanalysis.org/
Su escribe sobre muchos de ellos en su blog http://www.dumpanalysis.org/blog/
Si bien se trata principalmente de la depuración en las plataformas de Windows, ha comenzado a blog sobre gdb en Mac OS.