Gdb: точка останова, когда регистр будет иметь значение 0xffaa

Можно ли установить точку останова /watchpoint/smth else в gdb для значения регистра?

Я хочу сломать, когда $eax будет иметь значение 0x0000ffaa.

Возможно ли это с помощью gdb или dbx или любого другого отладчика unix?

Ответ 1

Да в gdb вы установили бы такую ​​точку наблюдения:

watch $eax == 0x0000ffaa

Но это зависит от поддержки точки наблюдения, доступной для цели. Следует отметить, что это может значительно замедлить выполнение.

Если вы хотите разбить определенное местоположение, вы можете сделать это, установив условную точку останова:

break test.c:120 if $eax == 0x0000ffaa

Ответ 2

Вниз:

Если вы используете $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

Ответ 3

Мне не удалось заставить его смотреть 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"

Ответ 4

Если вы находитесь на 64-битной машине, вы должны смотреть $rax, а не $eax.