Cómo utilizar un depurador

Esto es parte de una serie más grande conocida como “Cómo Programar Cualquier Cosa: Core Rulebook

Prefacio

Nota: En este artículo se describe el depurador visual promedio (un depurador con una interfaz gráfica de usuario) para un lenguaje imperativo, como C, Java, JavaScript, Python, PHP, etc. Si no está seguro de lo que significa imperativo, están usando el estilo de uno de estos idiomas listados, usted está en el lugar correcto.

Mientras que usted está programando usted tiene que tener presente cómo todas las piezas de cualquier sección usted está trabajando encendido trabajan junto. Usted está construyendo un flujo de programas y flujo de datos en abstracto, estando en su mente, mientras le dice a la computadora qué hacer. Cuando ejecuta el programa, la computadora ejecuta todas sus instrucciones cuidadosamente hechas a mano en una velocidad rápida y ardiente y obtiene sus resultados, ya sea una herramienta de línea de comandos que proporciona información textual o una interfaz gráfica de usuario con muchos botones o un mundo del juego completo con los modelos 3D. Y entonces, ocurre un error; algo no funciona bien o el programa se bloquea debido a una falla de segmentación o un personaje de un juego no responde por completo. ¿Que haces entonces? Desafortunadamente, parece que no puedes ralentizar la computadora, ver lo que está haciendo ya que ejecuta cada paso de tu programa para que puedas rastrear exactamente donde todo va mal … ¿o puedes?

Debugger son herramientas extremadamente útiles en la programación precisamente porque, en el ámbito general, hacen exactamente eso. Afortunadamente, los depuradores, como los entornos de desarrollo integrados (ver “¿Qué es un IDE?“), Han recorrido un largo camino en la usabilidad. Solía ​​ser que se ejecuta un depurador, como GDB desde la línea de comandos, y darle comandos en un formato textual como trabajó a través de su programa. Tenía que hacerlo cuando trabajaba como programador de trabajos de impresión para una planta de impresión de estados financieros, y no era divertido. De hecho, era confuso y extremadamente torpe.

En este artículo espero mostrarle los fundamentos de usar un depurador GUI que se puede aplicar a todos los entornos GUI de depuración (al menos para los programas imperativos). Como dice la nota anterior, si está programando un lenguaje de programación de uso general (imperativo) como C, Java, JavaScript, Python, PHP y tal, este artículo debería aplicarse a usted con pequeños cambios. Voy a cubrir los aspectos básicos de “paso a paso” a través del código, y luego pasar a lo que se conoce como puntos de interrupción. A lo largo del camino examinaremos las pilas de llamadas, el alcance y las variables. Por último, pasaremos a ver las expresiones, que no todos los depuradores tienen pero pueden demostrar ser una característica útil para saber.

Para darnos un ejemplo práctico, utilizaremos el depurador integrado que se incluye con el navegador web de Firefox. Realizaremos estas acciones básicas de depuración y mostraremos estos conceptos en la ejecución de un programa JavaScript simple. Existen depuradores para todos los principales navegadores, incluyendo Chrome y Safari, y originalmente iba a usar Safari como ejemplo. Sin embargo, descubrí que un gran número de versiones de Safari todavía no implementan expresiones de reloj, y este era un tema que quería cubrir. Así que, Firefox es entonces! He optado por emplear un algoritmo de selección de selección de dos funciones como mi ejemplo. Estaremos usando la consola JavaScript de Firefox en este ejemplo que es específico de JavaScript, pero la salida de datos de texto a StdOut o StdErr suele ser bastante sencillo en muchos otros idiomas como C o Python. Para “imprimir” estos flujos tendrás que consultar la referencia de tu idioma.

Colocándonos Arriba

Este tutorial en realidad tiene un poco de equipaje para descargar si quieres probarlo en casa, a diferencia de algunos de mis tutoriales anteriores sobre la naturaleza de las cosas y qué cosas son. Afortunadamente, no es mucho, simplemente consiste en un archivo con algunos extremadamente bare-bones HTML dentro de él, y el JavaScript que vamos a depurar. Para jugar en casa, simplemente descarga este archivo html y abre el archivo (debuggerexample.html) en la instalación del navegador web de Firefox. A continuación, en su menú, haga clic en “desarrollador” y, a continuación, “herramientas de conmutación”. Desde aquí, haga clic en la pestaña “depurador”. Debería ver algo como esto:

Haga clic para ver una versión más grande

Examinando el Código

Nuestro archivo HTML adjunto se compone de algunos elementos. El código HTML de base que compone la página (es decir, el texto de bienvenida, el campo de texto de entrada vacío, el texto de salida vacío y el botón de cálculo) tiene este aspecto:

El JavaScript, que contiene todo el código de nuestro programa se lee así:

El propósito de este código es ordenar una serie de números introducidos en el elemento HTML de entrada (separados por espacios) de “menor” (menor), a “mayor” (la mayoría), y la salida de esa lista de valores (separados por espacios) en el elemento HTML de salida. Este código consta de tres funciones (si no está familiarizado con las funciones y las variables, consulte mi artículo Programación de Crash Course Part 1). La primera función es un complemento de la segunda función y busca el valor mínimo en una lista que comienza en un índice particular y devuelve su índice. La segunda función es nuestro algoritmo de clasificación, y toma los siguientes pasos:

  1. Establezca el índice actual al principio de la lista: i = 0
  2. Comience en el índice actual y encuentre el valor más pequeño en la lista
  3. Intercambiar el valor en el índice actual con el valor más pequeño en la lista
  4. Incrementar el índice actual y repetir desde el paso 2 hasta llegar al final de la lista

La tercera función toma esta funcionalidad y “mapas” o la conecta en los elementos de formulario HTML que hemos construido. Esta función se ejecuta / se llama cada vez que alguien hace clic en el botón “calcular” en la página web.

Configuración de un punto de interrupción

Entonces, ¿cómo examinamos este código con un depurador? Bueno, lo primero que debemos hacer es indicar al depurador dónde queremos detener o detener la ejecución del código. Por ejemplo, si deseamos examinar la totalidad de este código desde el principio, un buen lugar para detener sería justo al principio de la función calcula (). Aquí es donde el concepto de puntos de interrupción es muy útil.

Esencialmente un punto de interrupción básico es un punto en el código indicado por el programador donde la ejecución del programa debe ser pausado y el control entregado al depurador. Vamos a “insertar” un punto de interrupción justo al principio de la función de cálculo, que está en la línea 31. Ahora, para indicar un punto de interrupción en el depurador de Firefox, simplemente haga clic en el número de línea a la izquierda del código para indicar donde nos gustaría hacer una pausa. Así que intente hacer clic en la línea 31 (el número de línea real) y debería ver algo como esto:

Esto le dice al navegador en este caso que tan pronto como alguien haga clic en el botón y calcula () se ejecuta, antes de empezar, haremos una pausa y el control de la mano sobre el depurador. Ahora si hago clic en el botón de cálculo mi pantalla debe cambiar ligeramente para indicar que estoy en el depurador y han ganado un control minucioso sobre mi programa. En este caso, los botones de “paso de código” deben estar activos.

Pasando a través del código

La parte inferior de la pantalla debería verse así:

Aquí está la carne y las patatas del depurador. Ahora estamos detenidos dentro del código. A la derecha podemos ver los valores de las variables que van a ser definidas y llenadas. En el código se resalta la línea en la que estamos pausados. El programa acaba de entrar en la primera función y está listo para comenzar a asignar variables. Lo que es más importante en este momento son lo que llamo los controles “paso a paso” en la parte superior izquierda. Estoy hablando de estos:

Estos son los botones que van a permitirle controlar cómo se ejecuta su programa a medida que examina su mecánica. De izquierda a derecha tenemos “step over”, “step into” y “step out of”. Cada tipo de paso hace algo específicamente diferente. Desde la parte superior:

  • “Step Into” – Si usted está en una línea donde una función se llama, esta herramienta en particular, en realidad “seguir” su código “en” esa función. El control se transferirá al principio de esa función, como si estuviera al principio del cálculo () con nuestro punto de interrupción. Por lo tanto, si estamos en la línea que contiene la llamada a selectionSort (), al hacer clic en este paso pasará al principio de selectionSort (). Si no estamos en una línea con una llamada de función, entonces esto simplemente pasos a la siguiente instrucción en el programa.
  • “Step Out Of” – Si está dentro de una función, este stepper ejecuta el resto de la función (con la restricción de que se ejecuta en cualquier otro punto de interrupción o error) y luego regresa a la línea en la que se introdujo “en” la función siendo la línea donde previamente se llamaba esa función.) Esto es útil si se realiza comprobando las instrucciones de una función y se necesita pasar al resto del programa.
  • “Step Over” – Ejecuta todas las instrucciones en una línea dada sin entrar “en” las funciones llamadas. Es básicamente un paso al botón de la siguiente línea. Si hay llamadas de función en una línea, se ejecutan, y la línea siguiente de donde está el control de programa actualmente recibirá el foco. Esto es útil si sabe que su función se llama funciona y desea pasar a otras partes del programa. No tiene que pasar por toda la función que se está llamando.

Sólo puede trabajar con los steppers si el programa ya está en pausa. Es por eso que tuvimos que establecer un punto de interrupción antes de poder acceder a los steppers.

Variables

Esto nos lleva a otra característica importante de los depuradores. A menudo muestran los valores de las diversas variables en los diversos ámbitos que son pertinentes para el momento en que el programa se pausa. De hecho, ahora que estamos al principio de la función de cálculo (), intente pasar por encima de las instrucciones en la función calcula () y observe a la derecha como las variables en este ámbito de función se definen y asignan a sus identificadores. Deberías terminar con algo así en el lado derecho de la ventana del depurador:

Siendo un depurador de JavaScript hay múltiples ámbitos que contienen sus propias variables, pero estamos interesados en las variables presentes en nuestra función calcula (). Como se puede ver como les asignamos paso a paso en la función, su representación se llena en nuestro inspector de variables. Esta es una herramienta muy útil porque puedes ver en tiempo real cómo se ve afectada una variable y qué valores tiene en la actualidad, en lugar de tener que seguirla en tu mente.

Muy bien, vamos a su botón de reproducción (a la izquierda de los controles paso a paso) y obtener el código para ejecutar completamente. Ahora, para eliminar el punto de interrupción en la línea 31, simplemente haga clic de nuevo en él. Esta vez vamos a establecer un punto de interrupción más “en” el programa (es decir, dos llamadas de función en su operación). Por lo tanto, establezca un punto de interrupción en la línea 7 dentro de la función findLeastRemaining (). Ahora, haga clic en el botón Calcular! botón una vez más.

Pila de llamadas

En la programación estructurada que utiliza las funciones de su común que una función llamará a otra función, que llamará a otra función, y así sucesivamente y así sucesivamente. Esto forma una especie de rastro de pan a través del programa, que la ejecución del programa sigue de un lado a otro mientras se ejecuta y regresa de las funciones que se están llamando. Esta ruta de ruta puede ser representada por la pila de llamadas. Se llama la pila de llamadas ya que como cada función es llamada, coloca la información de la función actual en una pila, literalmente apilándose en la parte superior de las referencias de funciones más antiguas en la memoria. Por lo tanto, si llamo a compute (), llamará a selectionSort () que a su vez llama a findLeastRemaining (), y cada una de estas llamadas registra una entrada en la pila. De hecho, podemos ver esta pila en nuestro depurador. En este momento, debería estar pausado en la línea 7 en la función findLeastRemaining (). A su izquierda hay una columna con dos pestañas, el ser de la derecha, lo adivinaste, “Call Stack”. Haga clic en que ahora, y la parte inferior izquierda de la pantalla debe verse algo como esto:

Esta es una herramienta increíblemente útil. Puede establecer un punto de interrupción en una función y, a continuación, averiguar cuándo y dónde se llama desde cualquier parte del código. Esto le permite ver cómo su programa llegó hasta el punto en el que llegó, y en este depurador en particular, si hace clic en una de las entradas, en realidad resaltará la línea en el código en el que se realizó esa llamada de función. ¡Hábil!

Punto de interrupción condicional

A veces un programa es tan repetitivo que usted no quiere ser atrapado en bucle después de bucle buscando una condición particular que se produzca. Usted sabe qué condición está ocurriendo que no está bien, y quiere afilar en esa situación particular. ¡Hay esperanza! No todos los depuradores tienen esto, pero muchos lo hacen. En Firefox puedes establecer un punto de interrupción condicional. Este es un punto de interrupción que depende de una expresión if-clause como que se evalúa como true o false. Si hace clic con el botón derecho en un punto de interrupción mientras está en el ámbito actual en Firefox, puede agregar una condición a ese punto de interrupción. Esto cambia el color del punto de interrupción de azul a naranja. Vamos a probarlo. Primero, haga clic en el punto de interrupción de línea 7 para borrarlo y, a continuación, haga clic en el botón Ejecutar a la izquierda de los controles paso a paso. Usted debe tener un plato limpio. Ahora haga clic en 22 y establezca un punto de interrupción. Haga clic derecho en este punto de interrupción y convertirlo en un punto de interrupción condicional. Mi Firefox era finicky de cuando podría realmente realizar esto así que usted puede tener que violín con él.

Ahora en esta parte de la lista de códigos list[i] va a igualar uno de los números que se están ordenando en un momento dado. Hagamos que nuestra if-cláusula de nuestro punto de interrupción condicional list[i] == 4  Ahora, ejecute el programa de nuevo haciendo clic en calcular ().

Debería ver algo como lo siguiente en la parte inferior de su pantalla:

Como puede ver, estamos detenidos en la línea 22. Si miramos a nuestra derecha y examinamos nuestras variables, veremos que i es igual a 2, y la segunda entrada en lista es igual a cuatro actualmente. Esto es justo en línea con nuestra condición. De hecho, la lista [i] no volverá a ser igual a cuatro después de esto, así que ejecuta hit y verás que es la única vez que el punto de interrupción es considerado por el depurador. Como se ha señalado, esta herramienta es de gran alcance cuando se desea comprobar o prestar atención a una situación particular en la programación sin slugging a través de muchas circunstancias en las que todo funciona bien.

Vea las expresiones

Esto nos lleva a mirar las expresiones. Estas son básicamente expresiones, usualmente simples identificadores de variables, que parpadean o muestran algún efecto específico cuando se cambian. Digamos que estoy en una función con una variable text1 que tiene un montón de propiedades. A través de la función muchas llamadas de función diferentes pueden afectar las propiedades de este objeto de varias maneras. Quiero saber cuando las propiedades de una variable en particular se cambian en el código ejecutado, la expresión que estoy siguiendo me puede decir fácilmente y rápidamente sin tener que pasar por grandes jerarquías de objetos.

Puede agregar una expresión de reloj en el depurador de Firefox simplemente seleccionando variables y haciendo clic con el botón derecho del ratón para seleccionar “hacer una expresión de reloj desde la selección”. O, puede introducir una expresión justo debajo de “agregar expresión de reloj” en el panel de variables. Esta es una característica de éxito de la mayoría de los compiladores, y muchos compiladores tienen esta característica, pero muchos no lo hacen.

Trate de experimentar con expresiones de reloj, entrando en diferentes expresiones, como minimumIndex y ver qué valores toma para sí mismo a medida que pasa a través del código. Esto le dará una idea si intenta varias variables sobre cómo funciona la función.

Conclusión

La depuración de programas es un trabajo duro. Puede requerir la máxima atención a cada pequeño detalle, y particularmente con el código de depuración que no escribió usted mismo, horas de slogging a través de las instrucciones específicas ordenadas de un programa para ver cómo funciona. Sin embargo, eso en sí mismo es invaluable, ya menudo ejecuto una pieza de software a través de un depurador para ver cómo funciona cuando no estoy familiarizado con el código.

En los “viejos tiempos” de Internet no había buenos depuradores JavaScript construidos en los navegadores web, y los desarrolladores debían depurar sus programas “a mano” y prueba y error. No he cubierto un número exhaustivo de métodos de depuración, ya que hay muchos que no implican necesariamente un depurador, pero he visto todo escrito sobre el tema y que está fuera del alcance de este artículo.

Muchos depuradores de esta naturaleza son similares, y en esto espero que lo que he esbozado aquí les será útil en el futuro. ¡Gracias por leer!

Esto es parte de una serie más grande conocida como “Cómo Programar Cualquier Cosa: Core Rulebook

Si usted aprecia este artículo usted puede ser que considere el apoyar de mi Patreon.

Pero si un compromiso mensual es un poco más, lo entiendo, podría considerar comprarme un café.

photo credit: sparr0 ICE-286 big board, pan 3 via photopin (license)

También te podría gustar...

Deja un comentario

A %d blogueros les gusta esto: