Tutoriales

7 consejos profesionales para usar el comando de paso GDB

Un depurador es un software que ejecuta su código y verifica cualquier problema que encuentre. depurador GNU (GBD) es uno de los depuradores más populares, en este artículo examino los depuradores de GDB step comando y comandos relacionados para varios casos de uso comunes.

Step es un comando muy utilizado, pero hay algunas cosas menos conocidas que pueden resultar confusas.Además, hay métodos que se pueden usar sin usar realmente step comando en sí mismo, por ejemplo, usando el menos conocido advance Ordenar.

[ Download now: Advanced Linux commands cheat sheet. ]

sin símbolos de depuración

Considere un programa de ejemplo simple:

#include 
int num() {
return 2;
}
void bar(int i)
{
printf("i = %d\n", i);
}
int main()
{
bar(num());
return 0;
}

Si primero compila sin símbolos de depuración, agregue el bar Entonces trata de entrar en él. GDB no reporta información de número de línea:

gcc exmp.c -o exmp
gdb ./exmp
(gdb) b bar
Breakpoint 1 at 0x401135
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, 0x0000000000401135 in bar ()
(gdb) step
Single stepping until exit from function bar,
which has no line number information.
i = 2
0x0000000000401168 in main ()

Estípite

Todavía es posible entrar en funciones sin información de número de línea, pero stepi El comando debe usarse en su lugar. Stepi solo ejecuta una instrucción a la vez.Al usar GDB stepi comando, a menudo es útil ejecutar primero display/i $pcEsto hace que el valor del contador del programa y la instrucción de máquina correspondiente se muestren después de cada paso:

(gdb) b bar
Breakpoint 1 at 0x401135
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, 0x0000000000401135 in bar ()
(gdb) display/i $pc
1: x/i $pc
=> 0x401135 : sub $0x10,%rsp

encima display Ordenar, i significa instrucciones de máquina y $pc es el registro del contador del programa.

Puede ser útil usar el registro de información e imprimir algunos contenidos del registro:

(gdb) info registers
rax 0x2 2
rbx 0x7fffffffdbc8 140737488346056
rcx 0x403e18 4210200
(gdb) print $rax
$1 = 2
(gdb) stepi
0x0000000000401139 in bar ()
1: x/i $pc
=> 0x401139 : mov %edi,-0x4(%rbp)

[ Learn how to manage your Linux environment for success. ]

llamadas a funciones complejas

Después de volver a compilar el programa de ejemplo con símbolos de depuración, puede encontrar el bar llame a main con su número de línea, luego intente ingresar bar otra vez:

gcc -g exmp.c -o exmp
gdb ./exmp
(gdb) b exmp.c:14
Breakpoint 1 at 0x401157: file exmp.c, line 14.
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, main () at exmp.c:14
14 bar(num());

ahora, entra bar():

(gdb) step
num () at exmp.c:4
4 return 2;

Los argumentos de una llamada de función deben procesarse antes de la llamada de función real, por lo que num() se espera que se ejecute antes bar() llamó.pero como entras bar, ¿como se esperaba?necesitas usar finish mando y step otra vez:

(gdb) finish
Run till exit from #0 num () at exmp.c:4
0x0000000000401161 in main () at exmp.c:14
14 bar(num());
Value returned is $1 = 2
(gdb) step
bar (i=2) at exmp.c:9
9 printf("i = %d\n", i);

interrumpir

Esto tbreak Comando para establecer un punto de interrupción temporal. Es útil en situaciones en las que no desea establecer un punto de interrupción permanente.Por ejemplo, si desea ingresar a una llamada de función compleja como f(g(h()), i(j()), ...) necesitas una larga lista de step/finish/step entrar en f Establecer un punto de interrupción temporal y luego usar continuar puede ayudar a evitar este tipo de secuencias.

Para demostrar esto, debe establecer un punto de interrupción para bar Llamar main justo como antes.Luego establezca un punto de interrupción temporal barComo punto de interrupción temporal, se elimina automáticamente después de presionar:

(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, main () at exmp.c:14
14 bar(num());
(gdb) tbreak bar
Temporary breakpoint 2 at 0x40113c: file exmp.c, line 9.

Después de llamar al punto de interrupción bar y establecer un punto de interrupción temporal barsolo necesitas continuar al final bar.

(gdb) continue
Continuing.
Temporary breakpoint 2, bar (i=2) at exmp.c:9
9 printf("i = %d\n", i);

[ Want to test your sysadmin skills? Take a skills assessment today. ]

deshabilitar comando

Como alternativa, puede utilizar el bar, continúe y luego deshabilite el segundo punto de interrupción cuando ya no sea necesario.De esta manera usted puede obtener el mismo tbreak Utilice un comando adicional:

(gdb) b exmp.c:14
Breakpoint 1 at 0x401157: file exmp.c, line 14.
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, main () at exmp.c:14
14 bar(num());
(gdb) b bar
Breakpoint 2 at 0x40113c: file exmp.c, line 9.
(gdb) c
Continuing.
Breakpoint 2, bar (i=2) at exmp.c:9
9 printf("i = %d\n", i);
(gdb) disable 2

Como puedes ver, info breakpoints visualización de comandos n por debajo Enb, lo que significa que está deshabilitado. Pero puede habilitarlo más tarde si es necesario nuevamente.

(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000401157 in main at exmp.c:14
breakpoint already hit 1 time
2 breakpoint keep n 0x000000000040113c in bar at exmp.c:9
breakpoint already hit 1 time
(gdb) enable 2
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040116a in main at exmp.c:19
breakpoint already hit 1 time
2 breakpoint keep y 0x0000000000401158 in bar at exmp.c:14
breakpoint already hit 1 time

Posicionamiento avanzado

Otra opción que puedes usar es advance Ordenar.reemplazar tbreak bar ; continuetu puedes hacer advance bar Este comando continúa ejecutando el programa hasta la posición dada.

otra cosa genial advance Sí, si no ha llegado al punto que está tratando de avanzar, GDB se detendrá después de que se complete la función del marco actual. Por lo tanto, la ejecución del programa está restringida:

Breakpoint 1 at 0x401157: file exmp.c, line 14.
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, main () at exmp.c:14
14 bar(num());
(gdb) advance bar
bar (i=2) at exmp.c:9
9 printf("i = %d\n", i);

Download RHEL 9 at no charge through the Red Hat Developer program. ]

función de salto

otra forma de entrar bar, evitar numesta usando skip Ordenar:

(gdb) b exmp.c:14
Breakpoint 1 at 0x401157: file exmp.c, line 14.
(gdb) skip num
Function num will be skipped when stepping.
(gdb) r
Starting program: /home/ahajkova/exmp
Breakpoint 1, main () at exmp.c:14
14 bar(num());
(gdb) step
bar (i=2) at exmp.c:9
9 printf("i = %d\n", i);

Para saber qué funciones se omiten actualmente, utilice info skip. Esto num Las funciones están marcadas como habilitadas para omitirse y:

(gdb) info skip
Num Enb Glob File RE Function
1 y n  n num

si skip Puede desactivarse (volver a activarse más tarde) o eliminarse por completo cuando ya no se necesite.puedes agregar otro skip y deshabilite el primero, luego elimínelos todos.deshabilitar un skipdebe especificar su número; si no se especifica, cada skip Desactivado.Funciona igual que habilitar o eliminar un skip:

(gdb) skip bar
(gdb) skip disable 1
(gdb) info skip
Num Enb Glob File RE Function
1 n n  n num
2 y n  n bar
(gdb) skip delete
(gdb) info skip
Not skipping any files or functions.

Comando de paso GDB

gdb step Los comandos son herramientas útiles para depurar aplicaciones. Hay varias formas de acceder incluso a funciones complejas, así que pruebe estas técnicas de GDB la próxima vez que esté solucionando problemas con su código.

[ Download the GNU Debugger cheat sheet ]


Esto apareció originalmente en sitio web de código abierto y republicado con permiso.

LEER  Captura paquetes en Kubernetes con esta herramienta de código abierto

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba