
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 $pc
Esto 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 bar
Como 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 bar
solo 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 ; continue
tu 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 num
esta 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 skip
debe 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.