GDB: точка останова, когда регистр будет иметь значение 0xffaa - PullRequest
19 голосов
/ 08 февраля 2010

Могу ли я установить точку останова / наблюдения / что-то еще в GDB для значения регистра?

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

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

Ответы [ 4 ]

27 голосов
/ 08 февраля 2010

Да, в GDB вы бы установили точку наблюдения следующим образом:

watch $eax == 0x0000ffaa

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

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

break test.c:120 if $eax == 0x0000ffaa
2 голосов
/ 18 марта 2010

Кому:

Если вы используете $ eax, условие игнорируется, и оно становится безусловной точкой наблюдения / останова.

<code>
(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<br>
End of assembler dump.</p>

<p>(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.</p>

<p>Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7               printf("hello %d\n", value);</p>

<p>(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.</p>

<p>Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7               printf("hello %d\n", value);
(gdb) </p>

<p>
Но $ rax работает как надо:
<code>
(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</p>

<p>Program exited normally.
(gdb) condition 1 $rax == 0
(gdb) run
Starting program: /home/dg/hello/hello 
hello world 2</p>

<p>Breakpoint 1, 0x00000000004005af in print_hello () at hello.c:7
7               printf("hello %d\n", value);
(gdb) 

Все это было проверено на GDB 6.8.50: GNU GDB (GDB; SUSE Linux Enterprise 11) 6.8.50.20081120-cvs

1 голос
/ 18 марта 2010

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

1 голос
/ 08 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...