Anuncios

Bienvenidos sean a este post, hoy veremos algunos comandos basicos de gdb.

Anuncios

En el post anterior hablamos sobre depuracion, y hablamos brevemente sobre gdb. Hoy nos centraremos en ver algunos comandos que dispone, asi como tambien aplicarlo y ver como trabaja con algunos codigos. En el post anterior vimos como instalarlo, en caso de no estarlo al momento de instalar lo esencial de C++, y por lo tanto podemos pasar a realizar algunas pruebas. Pero primero debemos crear el programa que usaremos, para ello deben crear un archivo y agregar el sigueinte codigo:

#include <iostream>

float sumar(float, float);

int main()
{
        float x = 15;
        float y = 20;
        float z = sumar(x, y);
        printf("x = %f, y = %f, z = %f\n", x, y, z);

        return 0;
}

float sumar(float a, float b)
{
        float ret = a + b;
        return ret;
}
Anuncios

Un codigo simple con una funcion que recibe dos valores, los suma entre si y devuelve el resultado de la operacionn y en el main definimos dos variables y en una tercera almacenamos el resultado de la funcion de los variables anteriores para finalmente mostrar los tres valores mediante printf. Antes de ver como es su resultado, veamos como se debe compilarlo para habilitar la depuracion:

$ g++ -g depurar.cpp -o depurar
Anuncios

Agregamos la opcion -g para que todo lo relacionado a la informacion para la depuracion se agregue al archivo ejecutable que creamos. Esto no altera en nada al archivo final pero si es un poco mas grande porque ahora tiene todo para la depuracion, y si lo ejecutan nos dara la siguiente salida:

$ ./depurar
x = 15.000000, y = 20.000000, z = 35.000000
$
Anuncios

Con todo esto comentado, podemos pasar a ver como se trabaja con el depurador, para ello deben ejecutarlo de la siguiente manera:

$ gdb depurar
Anuncios

Con esto ejecutado nos devolvera la siguiente ventana:

$ gdb depurar
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from depurar...
(gdb)
Anuncios

Esto indicara que estamos listo para comenzar la depuracion, lo primero que haremos sera crear un breakpoint y para ello ejecutaremos el siguiente comando:

(gdb) break main
Anuncios

Esto hara que el breakpoint se agrega en el main,, por lo tanto cuando lo ejecutemos mediante run llegara a este punto y se detendra, veamos lo que devuelve el depurador:

(gdb) run
Starting program: /home/tinchicus/lenguajes/cpp/07/depurar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at depurar.cpp:7
7               float x = 15;
(gdb)
Anuncios

Para esto se puede usar el primer caracter de los comandos que usamos. Por ejemplo, para break main podemos usar b main, o en lugar de run usar a r. En ambos casos, hara lo mismo de forma menos vistosa pero mas practica. Al principio, les conviene usar los comandos completos pero con el tiempo pueden usar las abreviaciones.

Anuncios

El siguiente comando que usaremos es print, este mostrara el valor de la variable en ese momento de ejecucion. Por ejemplo, mostremos el valor de z en el momento del breakpoint:

(gdb) print z
$1 = 0
(gdb)
Anuncios

En este caso, es cero porque todavia no le asignamos un valor. Recuerden que almacena el resultado de la funcion sumar. Nuestro siguiente comando es next, este pasa a la siguiente linea pero con la particularidad de que si llama a una subrutina no ingresara a la misma sino que la llamara. Veamos como trabaja:

(gdb) next
8               float y = 20;
(gdb)
Anuncios

Nos trajo la siguiente linea a la ultima que establecimos en el breakpoint. Existe otro comando de conducta similar a este llamado step pero su diferencia es que si ingresa a una subrutina si es llamado en la linea. Veamos como trabaja:

(gdb) step
9               float z = sumar(x, y);
(gdb) step
sumar (a=15, b=20) at depurar.cpp:17
17              float ret = a + b;
(gdb)
Anuncios

Observen como el primer step paso a la siguiente linea,, tal como la hace next, pero el segundo llamado a step nos manda a la funcion sumar y nos muestra a la primer linea donde hacemos la operacion. A partir de este momento, podemos usar tanto a step como next. Ejecuttemos una serie de los comandos anteriores para ver como avanza:

(gdb) step
9               float z = sumar(x, y);
(gdb) step
sumar (a=15, b=20) at depurar.cpp:17
17              float ret = a + b;
(gdb) next
18              return ret;
(gdb) step
19      }
(gdb) step
main () at depurar.cpp:10
10              printf("x = %f, y = %f, z = %f\n", x, y, z);
(gdb) print z
$2 = 35
(gdb)
Anuncios

Como pueden ver nos muestre cada una de las lineas que sigue y algunos valores que se movilizan de un lado a otro. Y al final, volvemos a usar a print para mostrar el valor de z y como ya esta asignado nos lo muestra en la consola. Sin un breakpoint nada de esto se hubiera podido realizar porque al usar run, nos mostraria como corre el programa. Otro comando interesante que disponemos es help, el cual nos permite obtener ayuda de todos los comandos o uno en especifico. Veamos como trabaja:

(gdb) help
List of classes of commands:

aliases -- User-defined aliases of other commands.
breakpoints -- Making program stop at certain points.
data -- Examining data.
files -- Specifying and examining files.
internals -- Maintenance commands.
obscure -- Obscure features.
running -- Running the program.
stack -- Examining the stack.
status -- Status inquiries.
support -- Support facilities.
text-user-interface -- TUI is the GDB text based interface.
tracepoints -- Tracing of program execution without stopping the program.
user-defined -- User-defined commands.

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb)
Anuncios

De forma basica nos devuelve los grupos donde se encuentran los comandos para determinadas tareas. Por ejemplo, veamos las de stack:

(gdb) help stack
Examining the stack.
The stack is made up of stack frames.  Gdb assigns numbers to stack frames
counting from zero for the innermost (currently executing) frame.

At any time gdb identifies one frame as the "selected" frame.
Variable lookups are done with respect to the selected frame.
When the program being debugged stops, gdb selects the innermost frame.
The commands below can be used to select other frames by number or address.

List of commands:

backtrace, where,
   bt -- Print backtrace of all stack frames, or innermost COUNT frames.
down, dow, do -- Select and print stack frame called by this one.
faas -- Apply a command to all frames (ignoring errors and empty output).
frame, f -- Select and print a stack frame.
frame address -- Select and print a stack frame by stack address.
frame apply -- Apply a command to a number of frames.
frame apply all -- Apply a command to all frames.
frame apply level -- Apply a command to a list of frames.
frame function -- Select and print a stack frame by function name.
frame level -- Select and print a stack frame by level.
frame view -- View a stack frame that might be outside the current backtrace.
return -- Make selected stack frame return to its caller.
select-frame -- Select a stack frame without printing anything.
select-frame address -- Select a stack frame by stack address.
select-frame function -- Select a stack frame by function name.
select-frame level -- Select a stack frame by level.
select-frame view -- Select a stack frame that might be outside the current backtrace.
up -- Select and print stack frame that called this one.

Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb)
Anuncios

Es una descripcion de que se encarga, asi como cada comando que la compone.. Para ver la ayuda de un comando simplemente pasamos a help seguido del mismo. Veamos alguna ayuda de uno de los comandos citados anteriormente:

(gdb) help break
break, brea, bre, br, b
Set breakpoint at specified location.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM]
        [-force-condition] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point.  Accepted values are `-probe' (for a generic, automatically
guessed probe type), `-probe-stap' (for a SystemTap probe) or
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a linespec, address, or explicit location as described
below.

With no LOCATION, uses current execution address of the selected
stack frame.  This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".
CONDITION is a boolean expression.

With the "-force-condition" flag, the condition is defined even when
it is invalid for all current locations.

Linespecs are colon-separated lists of location parameters, such as
source filename, function name, label name, and line number.
Example: To specify the start of a label named "the_top" in the
function "fact" in the file "factorial.c", use
"factorial.c:fact:the_top".

Address locations begin with "*" and specify an exact address in the
program.  Example: To specify the fourth byte past the start function
"main", use "*main + 4".

Explicit locations are similar to linespecs but use an option/argument
syntax to specify location parameters.
Example: To specify the start of the label named "the_top" in the
function "fact" in the file "factorial.c", use "-source factorial.c
-function fact -label the_top".

By default, a specified function is matched against the program's
functions in all scopes.  For C++, this means in all namespaces and
classes.  For Ada, this means in all packages.  E.g., in C++,
"func()" matches "A::func()", "A::B::func()", etc.  The
"-qualified" flag overrides this behavior, making GDB interpret the
specified name as a complete fully-qualified name instead.

Multiple breakpoints at one place are permitted, and useful if their
conditions are different.

Do "help breakpoints" for info on other commands dealing with breakpoints.
(gdb)
Anuncios

Este es en mas detalle para que sirve, asi de como obtener mas breakpoints para otras tareas. Antes de finalizar, para poder salir del depurador se puede usar al comando quit o como en las consolas de Unix mediante Ctrl+D. Veamos como trabaja::

(gdb) quit
A debugging session is active.

        Inferior 1 [process 18083] will be killed.

Quit anyway? (y or n) y
$
Anuncios

Cuando estemos depurando, como estuvimos haciendo ahora, nos consultara para poder salir pero de lo contrario saldra directamente. Con esto tenemos lo basico como para dar nuestros primeros pasos en la depuracion.

Anuncios

En resumen, hoy hemos visto unos comandos del depurador, desde como agregar un breakpoint (punto de interrupcion), correrlo, pasar a la siguiente linea, mostrar valores en el momento, asi como tambien poder obtener ayudas sobre los mismos y salir del depurador. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50