Debugging - Facultad de Ingeniería - Universidad de...

14
75.40 Algoritmos y Programación I Cátedra Ing. Pablo Guarna Debugging Ezequiel González Busquin

Transcript of Debugging - Facultad de Ingeniería - Universidad de...

Page 1: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

75.40 Algoritmos y Programación I

Cátedra Ing. Pablo Guarna

Debugging

Ezequiel González Busquin

Page 2: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 2

Contenidos Contenidos.................................................................................................................... 2

Versiones...................................................................................................................... 2

Etimología .................................................................................................................... 3

Bugs más comunes........................................................................................................ 5

División por cero ...................................................................................................... 5

Uso de variables sin inicializar .................................................................................. 5

Desbordamiento (overflow) de variables numéricas .................................................. 5

Pérdida de precisión en la conversión de tipos de datos numéricos ............................ 6

Ciclos infinitos.......................................................................................................... 6

Iteraciones fuera de rango ......................................................................................... 6

Instrucciones fuera del bloque................................................................................... 6

Variables pasadas por valor en lugar de pasadas por referencia ................................. 7

Desbordamiento de pila (Stack overflow).................................................................. 7

Asignación en lugar de preguntar por igual ............................................................... 7

Otros ......................................................................................................................... 7

Debugging .................................................................................................................... 8

Debugging en Free Pascal ......................................................................................... 8

Menú Run ............................................................................................................. 9

Menú Debug ......................................................................................................... 9

Conclusiones............................................................................................................... 12

Referencias ................................................................................................................. 14

Versiones

Versión Fecha Autor(es) Descripción

1.0 Marzo de 2008 Ezequiel González Busquin

egbusquin(arroba)gmail.com

Versión inicial

Page 3: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 3

“Si una secuencia de pasos puede fallar,

lo hará en la peor secuencia posible”

Ley de Murphy

Etimología

Si alguien busca la definición de bug en un diccionario de inglés descubrirá que

significa insecto o bicho. E inmediatamente se preguntará qué tienen que ver los

insectos con la programación.

Si bien el término ya se utilizaba en otras áreas de la ingeniería como ser la aeronáutica,

para la informática un bug es cualquier error, mal funcionamiento o falla que produce

que el software no funcione como se esperaba. La mayoría de los bugs provienen de los

errores cometidos al programar, aunque algunos otros pueden provenir de fallas en el

diseño y los menos de la conversión que los compiladores hacen del código fuente a

código de máquina.

Cuando se construyeron las primeras computadoras, que ocupaban cuartos enteros –

como ser la ENIAC (Fig. 1), durante los años 40 en Estados Unidos– la circuitería

consistía miles de elementos tales como relés, resistencias, capacitares y tubos de vacío.

Fig. 1: Computadora ENIAC

Los relés (Fig. 2) son llaves que abren y cierran circuitos eléctricos –tales como las

llaves de luz que utilizamos hoy en día—cuya activación se hace por medio de una

Page 4: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 4

corriente. Cuando esta corriente pasa a través de un electroimán se mueve una armadura

que abre o cierra el circuito.

Fig. 2: Relé abierto y cerrado

Las resistencias y tubos de vacío producían calor, lo cual atrae a los insectos. Si los

insectos morían entre los dos contactos de un relé, el circuito podía cerrarse (o no llegar

a hacerlo) lo cual producía resultados inesperados e incorrectos.

Fig. 3: Esta polilla es posiblemente el primer bug detectado en una computadora, encontrada por Grace

Hopper en la computadora Mark II de la Universidad de Harvard, el 9 de Septiembre de 1947.

Fig. 2: Relé abierto y cerrado

Page 5: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 5

Bugs más comunes

Entre los bugs más comunes que cometemos podemos encontrar

División por cero

La división por cero no está definida como operación matemática. Es por esto que si

intentamos dividir una variable por otra cuyo valor es cero, el programa se cuelga. La

ejecución es finalizada automáticamente.

Var a, b: integer;

Writeln('Ingrese los valores de A y B');

Readln (a, b);

Writeln (a, ' dividido ', b, ' resulta ser ', a / b );

{¡si b=0 se cuelga!}

Uso de variables sin inicializar

No siempre las variables toman un valor inicial, esto depende del lenguaje, del

compilador e incluso de opciones del compilador que son modificables por el usuario.

Una variable sin inicializar contiene “basura”, es decir, su valor es cualquier valor, dado

por la interpretación de los bytes en memoria que esa variable ocupa.

Var cantidad, acumulador: integer;

Repeat

Writeln (‘Ingrese cantidades, 0 para terminar’);

Readln (cantidad);

acumulador := acumulador + cantidad;

{¿inicialmente cuánto vale acumulador?}

Until cantidad = 0;

Desbordamiento (overflow) de variables numéricas

Dependiendo de la plataforma donde se esté trabajando y del tipo de variable, las

variables numéricas tienen un rango posible de valores. Por ejemplo un byte utiliza

siempre 8 bits. Con esta cantidad de bits se pueden representar hasta 28 = 256 cifras

distintas. Si se intenta almacenar un valor mayor en un byte se desborda su capacidad y

el valor resultante no es el esperado.

Existen opciones en el compilador que permiten que si se detecta un desbordamiento de

un entero se aborte la ejecución del programa.

Page 6: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 6

Var a, b, c: byte; {byte: números enteros de 0 a 255}

a := 250;

b := 10;

c := a + b;

writeln (a, ‘+’, b, ‘=’, c);

Pérdida de precisión en la conversión de tipos de datos numéricos

Este error sucede generalmente al asignar un valor con parte decimal a una variable

entera. El compilador automáticamente efectúa un redondeo (acercar al entero más

próximo) ó un truncamiento (uso sólo de la parte entera).

Número original Redondeado Truncado

5,24 5 5

2,99 3 2

4,5 5 4

7 7 7

Ciclos infinitos

Condiciones de corte de un ciclo iterativo que jamás se cumplen hacen que el ciclo

nunca termine y el programa se cuelgue. Si bien el programa sigue ejecutándose, jamás

terminará ni saldrá del ciclo, con lo cual para el usuario el programa ha dejado de

funcionar.

a := 1;

while (a = 1) do

begin

… {no se modifica el valor de a en el ciclo}

end;

Iteraciones fuera de rango

Al recorrer todos los elementos de un arreglo, lo más normal es utilizar un ciclo y una

variable de control que indica qué elemento del arreglo es el actual. Si la variable de

control supera el límite superior del arreglo se intenta acceder a una posición inexistente

del mismo. Este error es muchas veces detectado y el programa se interrumpe, pero

puede que esto no suceda y que se acceda a posiciones “basura” del arreglo.

Instrucciones fuera del bloque

Por errores de sangría o indentación (castellanización del término inglés indentation) en

el código puede confundirse qué sentencias están dentro o fuera de un bloque.

Page 7: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 7

Código original Código correcto var a, b;

Readln(a, b);

while (a < b) do

a := a + 1;

b := b – 1;

var a, b;

Readln(a, b);

while (a < b) do

begin

a := a + 1;

b := b – 1;

end;

Variables pasadas por valor en lugar de pasadas por referencia

Las variables que se pasan como parámetro a procedimientos y funciones por valor no

son modificadas dentro del procedimiento o función invocados, sino que se utiliza una

copia. Si se deseaba hacer modificaciones de las variables dentro del procedimiento

debe indicarse que su pasaje se realiza por referencia.

Desbordamiento de pila (Stack overflow)

El uso de procedimientos y funciones no es gratuito a nivel uso de memoria: Cada

invocación hace que el programa almacene desde dónde se invoca a la subrutina. Luego

se reserva la memoria necesaria para el uso de las variables locales. Al salir de la

subrutina la memoria de variables locales se libera y se retorna al lugar desde donde se

invocó.

Por consiguiente, el uso de una gran cantidad de llamadas a subrutina y de variables

locales puede llegar a saturar el tamaño de la memoria donde se almacena esa

información, denominada “pila”o “stack” de llamadas, provocando un desbordamiento

y un posterior cuelgue.

Asignación en lugar de preguntar por igual

Es un problema típico en C en y los lenguajes que derivan su sintaxis de ellos. Dado que

en C el operador de asignación es = y el de comparación por igual es == es común la

confusión y el incorrecto funcionamiento del programa.

Otros

Existen otros problemas muy comunes que son los principales bugs de la programación,

pero que dejamos fuera de análisis. Sin ser abarcativos y sólo para mencionar algunos,

diremos que están aquellos relacionados al uso de memoria dinámica:

• Referenciar un puntero nulo

• Acceso a memoria no solicitada: violación de acceso

• Desbordamiento de búfers (Buffer overflow)

• Pérdida de memoria dinámica (Memory leaks)

Page 8: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 8

Y aquellos que suceden cuando hay concurrencia:

• Abrazos mortales (Deadlocks)

• Condiciones de carrera (Race conditions)

Debugging

El debugging o depuración en informática se refiere a las acciones llevadas a cabo para

eliminar bugs del software.

Existen diversas técnicas de debugging, así como también herramientas específicas de

software denominados debuggers. Los debuggers están disponibles para casi todos los

lenguajes de programación y plataformas de desarrollo. Muchos de ellos se encuentran

integrados junto al compilador y un editor de texto en lo que se denomina IDE

(Integrated Development Enviroment, Entorno Integrado de Desarrollo) con lo cual

desde una misma aplicación o ventana se puede codificar un programa, compilar y

depurar.

El debugging del software es fundamental. Es necesario para entender cómo funciona

un programa y un arma poderosísima para la detección de problemas. Las técnicas van

desde el uso de banderas (por ejemplo, escribir por pantalla “Pasé por acá” para ver si

el flujo de un programa alcanza una determinada línea, “La variable X vale 3” para

visualizar el valor de una variable en un momento dado, etc) hasta el uso de breakpoints

y watches.

Debugging en Free Pascal

Una vez que tenemos el programa codificado, guardamos este código fuente del

programa como un archivo con extensión “.pas”. Luego, En Compile > Compile

invocamos al compilador de nuestro código fuente. El compilador se encargará de

transformar nuestro código fuente en código máquina o código ejecutable, que es el

código que entiende la computadora. Si tenemos errores, se desplegará una ventana

donde se nos indica cuál es, en qué línea del archivo fuente ocurre y una breve

descripción del mismo. El compilador puede de esta misma forma reportar advertencias

(warnings) sobre posibles errores cometidos. Un compilador por lo general toma una

decisión ante una advertencia que puede no resultar en lo que el programador quería, y

es por eso que la advertencia se genera. Haciendo ajustes en el código pueden

eliminarse (y es altamente recomendable) todas las advertencias de un programa.

En Free Pascal tenemos dos menúes que son de especial interés a la hora de hacer

debugging de un programa. Ellos son Debug y Run.

Page 9: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 9

Menú Run

Fig. 4: El menu Run de Free Pascal

Run (correr): Lanza a correr, ejecuta el programa. El mismo corre desde un principio

ejecutando cada sentencia del mismo una tras otra.

Step over (Pasar por encima): Ejecuta el programa desde la primera sentencia o desde

la sentencia actual, de a una sentencia a la vez. Si se encuentra una invocación a

subrutirna, no se entra en la misma, se la ejecuta como si fuera una sentencia común.

Trace into (Seguir adentro): Es igual que la opción anterior, pero ante una subrutina se

salta a su primera sentencia.

Goto cursor (Ir hasta el cursor): Ejecuta el programa hasta llegar a la línea sobre la cual

está posicionado el cursor actualmente.

Until return (Hasta un return): Ejecuta la subrutina hasta alcanzar la sentencia return o,

como caso particular, al programa principal hasta su finalización.

Program reset (Reinicio del programa): Inicia la ejecución del programa nuevamente

desde el principio.

Menú Debug

Output (Salida): Muestra la salida por pantalla del programa. Es lo que se vería si el

programa no se estuviera ejecutando desde el IDE.

User screen (Pantalla del usuario): Muestra la salida del programa en otra ventana del

IDE.

Page 10: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 10

Fig. 5: El menú Debug de Free Pascal

Add Watch (Agregar Visor): Agrega una variable para ser visto su valor en cada

instante.

Watches (Visores): Despliega la lista de variables bajo inspección.

Fig. 6: Un programa en Free Pascal con la ventana de watches. Se puede visualizar el valor de las

variables al haber llegado la ejecución a la línea actual. En rojo, el valor de la variable que se modificó en

la sentencia inmediata anterior.

Breakpoint (Punto de detención): Agrega a la sentencia bajo el cursor como punto de

detención en la ejecución del programa.

Page 11: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 11

Breakpoint List (Lista de Puntos de detención): Despliega una ventana con el listado

de breakpoints.

Fig. 7: Ventana con la lista de breakpoints del programa de la Fig. 6. El breakpoint de la línea 11 tiene la

condición de que el valor de la variable c sea menor que el de la a.

• Type (tipo): Existen diversos tipos de breakpoints, el más común es el file-line

que detiene la ejecución al llegar ésta a una sentencia determinada.

• Status (estado): Cada breakpoint puede activarse (enabled) o desactivarse

(disabled). Los breakpoints desactivados son ignorados, como si no existieran.

• Position (posición): Indica la línea y el archivo de código fuente donde está el

breakpoint.

• Conditions (condiciones): Pueden agregarse condiciones al breakpoint. Al

alcanzarse la sentencia donde está el breakpoint se evalúan las condiciones. Si

las mismas se cumplen, se detiene la ejecución del programa, en caso contrario

la ejecución continúa como si el breakpoint no existiese.

Evaluate (Evaluar): Al estar el programa en ejecución, permite evaluar expresiones

haciendo uso de las variables con visibilidad en el ámbito actual (como ser, variables

globales y las variables locales de la subrutina actual).

Call Stack (Pila de llamadas): Muestra el apilamiento de las invocaciones a subrutinas,

indicando desde qué línea se hizo la invocación, el nombre de la subrutina invocada y

en caso de existir, los parámetros actuales de invocación.

Page 12: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 12

Fig. 8: Pila de llamadas y ventana de watches en un pequeño programa

Existen otros comandos más avanzados y de uso no tan frecuente, los cuales son:

Disassemble (Desensamblar): Muestra el código assembler generado por el compilador

a partir del código fuente y permite su depuración, ejecución instrucción a instrucción,

etc.

Registers (Registros): Permite visualizar el estado de los registros de la CPU (Central

Processing Unit, Unidad Central de Procesamiento).

Floating point unit (Unidad de Punto Flotante): Permite visualizar el estado de la

unidad de punto flotante, que es un hardware especialmente diseñado para realizar

operaciones de punto flotante.

Vector unit (Unidad vectorial): Permite visualizar el estado de la unidad de cálculos

vectoriales, hardware específico para el manejo de operaciones vectoriales, de especial

interés en aplicaciones con gráficos 3D.

GDB window (Ventana GDB): GDB es el “GNU Debugger”. Es un debugger que

funciona en diversas plataformas y con distintos lenguajes de programación. GDB no

tiene una interfaz, sino que recibe los comandos en este caso desde la interfaz de Free

Pascal. Con esta ventana pueden darse a GDB instrucciones directas, en caso de ser

necesario.

Conclusiones

Los bugs del software son caros: su detección es complicada, insume horas de trabajo.

Su corrección puede también ser compleja, porque un pequeño cambio en un programa

puede tener consecuencias terribles alejadas en el tiempo y en el código. Desde hacer

Page 13: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 13

fallar una misión de la NASA hasta hacer que un cliente pierda sus datos y deje de

comprar nuestros productos, los bugs afectan económicamente a los proyectos y pueden

hacerlos fracasar. Un minucioso control, buenas prácticas de programación y un testing

eficiente del software hacen disminuir el riesgo.

Los bugs del software pueden ser mortales: han ocurrido casos en donde errores en la

programación de aparatos de medicina han provocado la muerte a pacientes.

Los bugs del software siempre están: no existe la posibilidad de armar un sistema

informático sin bugs: al crecer el sistema aumenta la complejidad y pueden darse

condiciones que no estuvieron contempladas desde un comienzo. Los bugs se producen

generalmente por errores humanos, nadie es perfecto y todos cometemos errores.

Es importante cada vez que se utiliza un nuevo entorno, un nuevo lenguaje de

programación, buscar, aprender y utilizar las herramientas para debug disponibles. Cada

vez hay más y mejores debuggers (¡incluso hay algunos que permiten hacer un debug

hacia atrás en el tiempo de ejecución!) y seguramente en el futuro más y mejores

aplicaciones harán cada vez más eficiente la erradicación de bugs.

Page 14: Debugging - Facultad de Ingeniería - Universidad de ...web.fi.uba.ar/~bortega/algoritmos_I/descargas/Debugging.pdf · Es un problema típico en C en y los lenguajes que derivan su

Universidad de Buenos Aires 75.40 Algoritmos y Programación I

Facultad de Ingeniería Cátedra Ing. Pablo Guarna

Técnicas de Debugging Página 14

Referencias

Imagen de la portada.

http://www.stevenbrown.ca/blog/archives/category/projects

Software bug.

http://en.wikipedia.org/wiki/Software_bug

GDB (GNU Debugger).

http://es.wikipedia.org/wiki/GNU_Debugger

Técnicas de Depuración (en Turbo Pascal 7.0). Augusto Vega.

http://www.geocities.com/algyprog_lopez/Depuracion.zip

Los peores bugs de la historia.

http://axxon.com.ar/not/156/c-1560164.htm

Debugging hacia atrás en el tiempo. Bil Lewis, Google TechTalks 2006.

http://video.google.com/videoplay?docid=3897010229726822034