Можно ли установить точку останова /watchpoint/smth else в gdb для значения регистра?
Я хочу сломать, когда $eax будет иметь значение 0x0000ffaa.
Возможно ли это с помощью gdb или dbx или любого другого отладчика unix?
Можно ли установить точку останова /watchpoint/smth else в gdb для значения регистра?
Я хочу сломать, когда $eax будет иметь значение 0x0000ffaa.
Возможно ли это с помощью gdb или dbx или любого другого отладчика unix?
Да в gdb вы установили бы такую точку наблюдения:
watch $eax == 0x0000ffaa
Но это зависит от поддержки точки наблюдения, доступной для цели. Следует отметить, что это может значительно замедлить выполнение.
Если вы хотите разбить определенное местоположение, вы можете сделать это, установив условную точку останова:
break test.c:120 if $eax == 0x0000ffaa
Вниз:
Если вы используете $eax, условие игнорируется и становится безусловной секундомерью/точкой останова.
(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
End of assembler dump.
(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)
But $rax works as it should:
(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
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)
This was all tested on gdb 6.8.50: GNU gdb (GDB; SUSE Linux Enterprise 11) 6.8.50.20081120-cvs
Мне не удалось заставить его смотреть eax напрямую, поэтому я ввел несколько инструкций asm, чтобы сохранить требуемое значение для мусорной переменной и наблюдать за этим. Я не смог убедить gcc использовать eax, поэтому этот код "смотрит" вместо 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;
}
Теперь вы можете "смотреть tmp"
Если вы находитесь на 64-битной машине, вы должны смотреть $rax
, а не $eax
.