¿Cómo depurar el código más efectivamente? [cerrado]

33

Los errores que se introducen en el código pueden minimizarse, pero no eliminarse por completo como está escrito: los programadores son, aunque muchos estarían en desacuerdo , solo humanos.

Cuando detectamos un error en nuestro código, ¿qué podemos hacer para eliminarlo? ¿Cómo deberíamos abordarlo para hacer un uso más eficaz de nuestro valioso tiempo y permitirnos pasar menos tiempo tratando de encontrarlo y más tiempo codificando? Además, ¿qué debemos evitar al depurar?

Tenga en cuenta aquí que no estamos hablando de prevenir errores; estamos hablando de qué hacer cuando los errores no aparecen. Este es un campo amplio, lo sé, y puede depender mucho del lenguaje, la plataforma y las herramientas. Si es así, siga las respuestas generales, como la mentalidad y los métodos generales.

gablin
fuente
Se ha eliminado la pregunta vinculada.
1
Creo que el enfoque es realmente simple. Si lo desarrolló solo, ya lo sabe todo. Incluso puede corregir el error sin depurarlo. Con eso en mente, la mejor manera es usar su tiempo para codificar otra cosa, hasta que alguien que sepa mucho sobre eso pueda responder su pregunta sobre cómo solucionarlo; o, déjalo descansar, codifica otras cosas, hasta que se te ocurra una idea para arreglarlo, para que no pierdas tiempo ni energía. Supongo que su pregunta es sobre la gestión del equipo empresarial.
Acuario Power
Creo que Raid. Spray que mata insectos y listo para usar. ¿Es esta una pregunta filosófica? Los libros están hechos de la mera preponderancia ...
ejbytes

Respuestas:

38

La mentalidad y la actitud ante la depuración es quizás la parte más importante, porque determina qué tan efectivamente solucionará el error y qué aprenderá de él, en todo caso.

Los clásicos sobre el desarrollo de software como The Pragmatic Programmer y Code Complete básicamente defienden el mismo enfoque: cada error es una oportunidad para aprender, casi siempre sobre usted (porque solo los principiantes culpan primero al compilador / computadora).

Así que trátalo como un misterio que será interesante de descifrar. Y descifrar ese misterio debe hacerse sistemáticamente, expresando nuestras suposiciones (para nosotros mismos o para los demás) y luego probando nuestras suposiciones, una por una si es necesario, utilizando todas las herramientas a nuestra disposición, especialmente los depuradores y los marcos de prueba automatizados. Luego, una vez que se resuelva el misterio, puede hacerlo aún mejor si busca en todo su código errores similares que haya cometido; y escriba una prueba automatizada para asegurarse de que el error no vuelva a ocurrir sin saberlo.

Una última nota: prefiero llamar a los errores "errores" y no "errores": Dijkstra reprendió a sus colegas por usar el último término porque es deshonesto, apoyando la idea de que las hadas de insectos perniciosas y volubles plantaron errores en nuestros programas mientras nosotros no estábamos ' mirando, en lugar de estar allí debido a nuestro propio pensamiento (descuidado): http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

Podríamos, por ejemplo, comenzar limpiando nuestro lenguaje ya no llamando a un error un error, sino llamándolo un error. Es mucho más honesto porque culpa directamente a donde pertenece, a saber. con el programador que cometió el error. La metáfora animista del error que se introdujo maliciosamente mientras el programador no estaba mirando es intelectualmente deshonesto, ya que oculta que el error es creación propia del programador. Lo bueno de este simple cambio de vocabulario es que tiene un efecto tan profundo: mientras que antes, un programa con un solo error solía ser "casi correcto", después un programa con un error es simplemente "incorrecto" (porque en error).

limist
fuente
77
En realidad, me gusta el término "error" en lugar de "error", no porque culpe al "programador que cometió el error", sino porque deja en claro que podría no haber sido el culpable del programador. Para mí, "error" implica error en el código; mientras que "error" implica error en alguna parte . Tal vez en el código, tal vez en la configuración del entorno, tal vez en los requisitos. Me vuelve loco cuando mi jefe tiene una "lista de errores" donde la mitad de los problemas son cambios de requisitos. ¡Llámalo lista de tareas, ferchrissakes!
Carson63000
2
+1 para "cada error es una oportunidad para aprender, casi siempre sobre usted (porque solo los principiantes culpan primero al compilador / computadora)"
Md Mahbubur Rahman
Conoces el historial del término "error", ¿verdad? Quiero decir, como se usa en el desarrollo de software. Por supuesto, hoy no tenemos este problema, pero un error en realidad sí que pasó al hardware de una computadora sin ser notado por el programador y causó un problema. Para que alguien piense en corregirme, sé que Edison usó este término mucho antes del incidente de la polilla, por eso usé la palabra "historia", no "origen". Ver computerworld.com/article/2515435/app-development/… y en.wikipedia.org/wiki/Software_bug#Etymology
trillado
@threed Por supuesto. Pero durante bastante tiempo, los insectos no han causado la gran mayoría de los errores de software.
Limista
16
  1. Escribe exámenes. Las pruebas no solo son excelentes para prevenir errores (en mi experiencia, TDD hecho correctamente elimina casi todos los errores triviales y estúpidos), sino que también ayuda mucho en la depuración. Las pruebas obligan a que su diseño sea bastante modular, lo que facilita mucho el aislamiento y la replicación del problema. Además, controlas el entorno, por lo que habrá muchas menos sorpresas. Además, una vez que obtiene un caso de prueba fallido, puede estar razonablemente seguro de haber aclarado la verdadera razón del comportamiento que le está molestando.

  2. Aprende a usar un depurador. printlas declaraciones pueden funcionar razonablemente bien en algún nivel, pero un depurador la mayor parte del tiempo es muy útil (y una vez que sabe cómo usarlo, es mucho más cómodo que las printdeclaraciones).

  3. Habla sobre alguien sobre tu problema, incluso si es solo un patito de goma . Obligarse a expresar el problema en el que está trabajando con palabras realmente hace milagros.

  4. Date un límite de tiempo. Si, por ejemplo, después de 45 minutos siente que no va a ninguna parte, simplemente cambie a otras tareas por algún tiempo. Cuando regrese a su error, con suerte podrá ver otras posibles soluciones que no habría considerado antes.

Ryszard Szopa
fuente
2
+1 para "Obligarse a expresar el problema en el que está trabajando con palabras realmente hace milagros".
Md Mahbubur Rahman
Y para agregar a (1), casi todos los errores que ve en el código implican que hay un error, o al menos una omisión, en el conjunto de pruebas. Solucione ambos al mismo tiempo y no solo demuestra que ha solucionado el problema en cuestión, sino que está seguro de que no se reintroduzca.
Julia Hayward
3

Creo que la reproducción de un error también es importante. Todos los casos que reproducen el error se pueden enumerar y luego puede asegurarse de que su corrección de errores cubra todos esos casos.

aslisabanci
fuente
3

Hay un excelente libro que leí sobre este tema llamado Por qué fallan los programas , que describe varias estrategias para encontrar errores que van desde la aplicación del método científico para aislar y resolver un error, hasta la depuración delta. La otra parte interesante de este libro es que elimina el término 'error'. El enfoque de Zeller es:

(1) Un programador crea un defecto en el código. (2) El defecto causa una infección (3) La infección se propaga (4) La infección causa una falla.

Si desea mejorar sus habilidades de depuración, le recomiendo este libro.

En mi propia experiencia personal, he encontrado muchos errores en nuestra aplicación, pero la administración simplemente nos presiona para obtener nuevas funciones. Con frecuencia escuché "Encontramos este error nosotros mismos y el cliente aún no lo ha notado, así que déjelo hasta que lo hagan". Creo que ser reactivo en lugar de proactivo en la corrección de errores es una muy mala idea, ya que cuando llega el momento de solucionarlo, tiene otros problemas que deben resolverse y más funciones de administración quieren salir de la puerta lo antes posible, por lo que queda atrapado en un círculo vicioso que puede conducir a una gran cantidad de estrés y agotamiento y, en última instancia, a un sistema lleno de defectos.

La comunicación también es otro factor cuando se encuentran errores. Enviar un correo electrónico o documentarlo en el rastreador de errores está bien, pero según mi propia experiencia, otros desarrolladores encuentran un error similar y en lugar de reutilizar la solución que colocaste para arreglar el código (ya que lo han olvidado por completo) ), agregan sus propias versiones, por lo que tiene 5 soluciones diferentes en su código y, como resultado, se ve más hinchado y confuso. Por lo tanto, cuando solucione un error, asegúrese de que algunas personas lo revisen y le den su opinión en caso de que hayan solucionado algo similar y hayan encontrado una buena estrategia para tratarlo.

Limist mencionó el libro, El programador pragmático, que tiene material interesante sobre la corrección de errores. Usando el ejemplo que di en el párrafo anterior, miraría esto: Software Entrophy , donde se usa la analogía de una viuda rota. Si aparecen dos ventanas rotas, su equipo puede mostrarse apático para solucionarlo a menos que adopte una postura proactiva.

Planeta desolado
fuente
Escuché "Encontramos este error nosotros mismos y el cliente aún no lo ha notado, así que déjelo hasta que lo hagan" también muchas veces. Y después de haber realizado visitas al sitio, a menudo el cliente se ha dado cuenta, pero no lo ha informado. A veces porque piensan que no tiene sentido porque no se solucionará, a veces porque ya están buscando el reemplazo de un competidor, y a veces (correcta o incorrectamente) "bueno, de todos modos todo es un montón de basura".
Julia Hayward
@JuliaHayward: este suele ser el caso, pero en su situación, sus clientes pueden estar satisfechos con la funcionalidad y no preocuparse demasiado por lo que sucede debajo del capó. El problema comienza a surgir cuando el cliente regresa pidiendo características adicionales y necesita agregar otras mejoras, como hacer que su aplicación sea multilingüe, compatible con dispositivos móviles, bla, bla, comienza a mirar lo que tiene y ve todas las grietas en la pared.
Desolate Planet
Solo le muestra que todos los libros del mundo sobre diseño de software, pruebas y buena comunicación, y muchos de los productos en los que trabaja son un desastre. A pesar de saber lo que es correcto, el estrés y los plazos poco realistas (en vista de su código ya desordenado) son las razones detrás de por qué el código está en el estado en que se encuentra. No tengo ninguna respuesta para mí, soy bastante distinguido en la oficina como una cara gimiendo ****** mientras pateo y grito para mantener el código saludable y el proceso de desarrollo sin problemas, pero a veces el equipo no lo hace. Se unen bien juntos.
Desolate Planet
3

Error, error, problema, defecto: como quiera llamarlo, no hace mucha diferencia. Seguiré con el problema, ya que es a lo que estoy acostumbrado

  1. Averigüe cuál es la percepción del problema: traduzca de un cliente 'Bob todavía no está en el sistema' a 'Cuando trato de crear un registro de usuario para Bob, falla con una excepción de clave duplicada, aunque Bob ya no está ahí'
  2. Averigüe si realmente es un problema o simplemente un malentendido (de hecho, Bob no está allí, no hay nadie llamado bob, y la inserción debería funcionar).
  3. Intente obtener pasos confiables mínimos que pueda seguir para reproducir el problema, algo como 'Dado un sistema con un registro de usuario' Bruce ', cuando se inserta un registro de usuario' Bob ', se produce una excepción'
  4. Esta es su prueba: si es posible, colóquela en un arnés de prueba automatizado que pueda ejecutar una y otra vez, esto será invaluable al depurar. También puede incluirlo en su conjunto de pruebas para asegurarse de que ese problema en particular no vuelva a aparecer más adelante.
  5. Obtenga su depurador y comience a poner puntos de interrupción: descubra la ruta del código cuando ejecute su prueba e identifique lo que está mal. Mientras lo hace, también puede refinar su prueba haciéndola lo más angosta posible, idealmente una prueba unitaria.
  6. Arreglalo - verifica tus pases de prueba.
  7. Verifique que el problema original según lo descrito por el cliente también esté solucionado (muy importante, es posible que haya solucionado un subconjunto del problema). Verifique que no haya introducido regresiones en otros aspectos del programa.

Si está muy familiarizado con el código, o si el problema o la solución es obvio, puede omitir algunos de esos pasos.

¿Cómo deberíamos abordarlo para hacer un uso más eficaz de nuestro valioso tiempo y permitirnos pasar menos tiempo tratando de encontrarlo y más tiempo codificando?

Estoy en desacuerdo con eso, ya que implica que escribir un nuevo código es un movimiento valioso que tener un programa de trabajo de alta calidad. No hay nada de malo en ser lo más efectivo posible para solucionar problemas, pero un programa no necesariamente mejora simplemente agregando más código.

ptyx
fuente
esta es la mejor respuesta OMI
marcusshep
3

Me gustan la mayoría de las otras respuestas, pero aquí hay algunos consejos sobre qué hacer ANTES de hacer algo de eso. Te ahorrará beaucoup de time.

  1. Determine si realmente hay un error. Un error SIEMPRE es una diferencia entre el comportamiento del sistema y los requisitos; el probador debería poder articular el comportamiento esperado y el real. Si no puede proporcionar apoyo para el comportamiento esperado, no hay ningún requisito y no hay error, solo la opinión de alguien. Devuelvelo.

  2. Considere la posibilidad de que el comportamiento esperado sea incorrecto. Esto podría deberse a una mala interpretación del requisito. También podría deberse a un defecto en el requisito en sí mismo (un delta entre un requisito detallado y un requisito comercial). Puede enviarlos de vuelta también.

  3. Aísla el problema. Solo la experiencia le enseñará la forma más rápida de hacerlo: algunas personas casi pueden hacerlo con sus instintos. Un enfoque básico es variar una cosa mientras se mantienen constantes todas las demás (¿el problema ocurre en otros entornos? Con otros navegadores? En una región de prueba diferente? En diferentes momentos del día?) Otro enfoque es mirar los volcados de pila o mensajes de error: a veces puede darse cuenta por la forma en que está formateado qué componente del sistema arrojó el error original (por ejemplo, si está en alemán, puede culpar a ese tercero con el que trabaja en Berlín).

  4. Si lo ha reducido a dos sistemas que colaboran, inspeccione los mensajes entre los dos sistemas a través de un monitor de tráfico o archivos de registro, y determine qué sistema se comporta según las especificaciones y cuál no. Si hay más de dos sistemas en el escenario, puede realizar comprobaciones por pares y "bajar" la pila de aplicaciones.

  5. La razón por la cual es tan importante aislar el problema es que el problema puede no ser debido a un defecto en el código sobre el que usted tiene control (por ejemplo, sistemas de terceros o el entorno) y desea que esa parte se haga cargo lo más rápido posible . Esto es tanto para ahorrarle trabajo como para ponerlos en práctica de inmediato, de modo que se pueda lograr la resolución en el menor tiempo posible. No desea trabajar en un problema durante diez días solo para descubrir que realmente es un problema con el servicio web de otra persona.

  6. Si ha determinado que realmente hay un defecto y realmente está en el código que controla, puede aislar aún más el problema buscando la última compilación "conocida" e inspeccionando los registros de control de origen para detectar cambios que puedan haber causado el problema. Esto puede ahorrar mucho tiempo.

  7. Si no puede resolverlo desde el control de origen, ahora es el momento de adjuntar su depurador y recorrer el código para resolverlo. Es probable que a estas alturas ya tenga una idea bastante buena del problema.

Una vez que sepa dónde está el error y pueda pensar en una solución, este es un buen procedimiento para solucionarlo:

  1. Escriba una prueba unitaria que reproduzca el problema y falle.

  2. Sin modificar la prueba unitaria, hágala pasar (modificando el código de la aplicación).

  3. Mantenga la prueba unitaria en su conjunto de pruebas para prevenir / detectar regresión.

John Wu
fuente
1

Así es como lo hago:

  1. use el mismo método cada vez que encuentre el problema. Esto mejorará su tiempo de reacción a los errores.
  2. La mejor manera es probablemente leer el código. Esto se debe a que toda la información está disponible en el código. Solo necesita formas eficientes de encontrar la posición correcta y la capacidad de comprender todos los detalles.
  3. la depuración es muy lenta, y solo es necesaria si sus programadores aún no entienden cómo la computadora ejecuta las instrucciones asm / no pueden entender las pilas de llamadas y cosas básicas
  4. Trate de desarrollar técnicas de prueba como usar prototipos de funciones para razonar sobre el comportamiento del programa. Esto ayudará a encontrar la posición correcta más rápido
tp1
fuente
1

Cuando detectamos un error en nuestro código, ¿qué podemos hacer para eliminarlo? ¿Cómo deberíamos abordarlo para hacer un uso más eficaz de nuestro valioso tiempo y permitirnos pasar menos tiempo tratando de encontrarlo y más tiempo codificando? Además, ¿qué debemos evitar al depurar?

Suponiendo que se encuentra en un entorno de producción, esto es lo que debe hacer:

  1. Describa el "error" correctamente e identifique los eventos que hacen que suceda.

  2. Determine si el "error" es un error de código o error de especificación. Por ejemplo, ingresar un nombre de 1 letra puede considerarse un error para algunos sistemas, pero un comportamiento aceptable para otros sistemas. A veces, un usuario informaría un error que él / ella cree que es un problema, pero la expectativa del usuario sobre el comportamiento del sistema no era parte de los requisitos.

  3. Si ha demostrado que hay un error y el error se debe al código, puede determinar qué partes del código deben repararse para evitar el error. También examine el efecto del comportamiento en los datos actuales y las operaciones futuras del sistema (análisis de impacto en el código y los datos).

  4. En este punto, probablemente tenga una estimación de la cantidad de recursos que se consumirán para solucionar el error. Puede arreglarlo de inmediato o programar una solución dentro de una próxima versión del software. Esto también depende de si el usuario final está dispuesto a pagar por la solución. También debe evaluar las diferentes opciones disponibles para corregir el error. Puede haber más de una forma. Debe seleccionar el enfoque que mejor se adapte a la situación.

  5. Analice las razones que causaron la aparición de este error (requisitos, codificación, pruebas, etc.). Haga cumplir los procesos que evitarían que la condición vuelva a ocurrir.

  6. Documente el episodio adecuadamente.

  7. Suelte la corrección (o la nueva versión)

Ninguna posibilidad
fuente