当特定变量设置为特定值时,有没有办法让gdb暂停?例如,如果某个范围内存在变量x,则在程序执行的某个时刻将其设置为4。当x设置为4时,如何指示gdb暂停执行?
答案 0 :(得分:4)
当特定变量设置为特定值时,有没有办法让gdb暂停?
是:您可以设置观察点,并且可以使其成为条件。
首先是一个微不足道的案例:变量是全局的(因此它的地址永远不会改变):
$ cat tt.c
int foo;
void bar() { foo += 1; }
void baz() { foo += 2; }
int main()
{
baz(); bar(); baz();
return 0;
}
$ gcc -g tt.c && gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) watch foo
Hardware watchpoint 1: foo
(gdb) cond 1 foo == 3
(gdb) r
Starting program: /tmp/a.out
Hardware watchpoint 1: foo
Old value = 2
New value = 3
0x00000000004004c7 in bar () at tt.c:3
3 void bar() { foo += 1; }
(gdb) quit
第二个简单的例子:变量是本地的,并且始终位于相同的堆栈位置:
$ cat t.c
int main()
{
int i, sum = 0;
for (i = 0; i < 10; ++i) {
sum += i;
}
return 0;
}
$ gcc -g t.c && gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) b 5
Breakpoint 1 at 0x4004bf: file t.c, line 5.
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, main () at t.c:5
5 for (i = 0; i < 10; ++i) {
(gdb) watch sum
Hardware watchpoint 2: sum
(gdb) cond 2 sum == 36
(gdb) c
Continuing.
Hardware watchpoint 2: sum
Old value = 28
New value = 36
main () at t.c:5
5 for (i = 0; i < 10; ++i) {
(gdb) quit
最后,一个棘手的案例:局部变量在堆栈上的位置发生了变化(例如,因为它所处的函数是递归调用的,或来自不同的上下文):
$ cat foo.c
int foo(int x)
{
int y = x + x;
return y;
}
int recursive(int x, int y)
{
if (x > 0)
return recursive(x - 1, y + 1);
return foo(y);
}
int main()
{
printf("recursive(1,0) = %d\n", recursive(1, 0));
printf("recursive(2,0) = %d\n", recursive(2, 0));
printf("recursive(3,0) = %d\n", recursive(3, 0));
return 0;
}
$ gcc -g foo.c && gdb -q ./a.out
(gdb) b foo
Breakpoint 1 at 0x4004fb: file foo.c, line 3.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>watch y
>cond $bpnum y == 4
>c
>end
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, foo (x=1) at foo.c:3
3 int y = x + x;
Hardware watchpoint 2: y
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
recursive (x=0, y=1) at foo.c:12
12 }
此处GDB已停止,因为观察点无效。我不知道如何让它静静地移除观察点并继续。
(gdb) c
Continuing.
recursive(1,0) = 2
Breakpoint 1, foo (x=2) at foo.c:3
3 int y = x + x;
Hardware watchpoint 3: y
Hardware watchpoint 3: y
Old value = 0
New value = 4
foo (x=2) at foo.c:4
4 return y;
钽DAH!
(gdb) bt
#0 foo (x=2) at foo.c:4
#1 0x000000000040053d in recursive (x=0, y=2) at foo.c:11
#2 0x0000000000400531 in recursive (x=1, y=1) at foo.c:10
#3 0x0000000000400531 in recursive (x=2, y=0) at foo.c:10
#4 0x0000000000400572 in main () at foo.c:17