debugging - tutorial - gdb: punto de interrupción cuando el registro tendrá valor 0xffaa
gdb tutorial español (4)
A la pizca
Si usa $ eax, la condición se ignora y se convierte en un punto de interrupción / vigilancia incondicional.
(gdb) break *0x00000000004005af if $eax==0
Breakpoint 1 at 0x4005af: file hello.c, line 7.
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005af in print_hello at hello.c:7
stop only if $eax==0
(gdb) run
Starting program: /home/dg/hello/hello
hello world 2
Error in testing breakpoint condition:
Invalid type combination in equality test. Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7 printf("hello %d/n", value); (gdb) condition 1 $eax != 0
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/dg/hello/hello
hello world 2
Error in testing breakpoint condition:
Invalid type combination in equality test. Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7 printf("hello %d/n", value);
(gdb)
(gdb) disass print_hello
Dump of assembler code for function print_hello:
0x000000000040058c : push %rbp
0x000000000040058d : mov %rsp,%rbp
0x0000000000400590 : sub $0x20,%rsp
0x0000000000400594 : movl $0x1,-0x4(%rbp)
0x000000000040059b : movl $0x5,-0x4(%rbp)
0x00000000004005a2 : mov -0x4(%rbp),%esi
0x00000000004005a5 : mov $0x4006dc,%edi
0x00000000004005aa : mov $0x0,%eax
0x00000000004005af : callq 0x400468
0x00000000004005b4 : leaveq
0x00000000004005b5 : retq
Pero $ rax funciona como debería:
End of assembler dump.
Program exited normally.
(gdb) condition 1 $rax == 0
(gdb) run
Starting program: /home/dg/hello/hello
hello world 2 Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7 printf("hello %d/n", value);
(gdb)
(gdb) condition 1 $rax != 0
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005af in print_hello at hello.c:7
stop only if $rax != 0
breakpoint already hit 1 time
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/dg/hello/hello
hello world 2
hello 5
Todo esto se probó en gdb 6.8.50: GNU gdb (GDB; SUSE Linux Enterprise 11) 6.8.50.20081120-cvs
¿Puedo establecer el punto de interrupción / punto de observación / smth else en gdb para el valor de registro?
Quiero romper cuando $ eax tendrá valor 0x0000ffaa.
¿Es posible con gdb o dbx o cualquier otro depurador de Unix?
No pude verlo directamente a través de eax, así que inserté algunas instrucciones de asm para almacenar el valor requerido en una variable basura y lo observé. No pude convencer a gcc de usar eax, por lo que este código "mira" a ebx.
#include <stdio.h>
int tmp;
int main(void)
{
int i;
printf("tmp is originally %d/n",tmp);
for(i=0;i<20;i++)
{
asm (
"cmpl $10,%ebx/n"
"jne dont/n"
"movl %ebx,tmp/n"
"dont:/n"
);
printf("%d/n",i);
printf("/nnow tmp is %d/n",tmp);
return 0;
}
Ahora puedes "ver tmp"
Sí, en gdb deberías establecer un punto de observación como el siguiente:
watch $eax == 0x0000ffaa
Pero depende de que el soporte de puntos de observación esté disponible para el objetivo. Debe tener en cuenta que esto puede ralentizar significativamente la ejecución.
Si desea ingresar en un lugar determinado, puede hacerlo estableciendo un punto de interrupción condicional:
break test.c:120 if $eax == 0x0000ffaa
Si está en una máquina de 64 bits, debe mirar $rax
, no $eax
.