gdb 调试-观察点

1. 设置观察点

gdb 通过 watch 命令设置观察点,也就是当一个变量值发生变化时,程序就会停下来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// code
int a = 0;
void *thread1_func(void *p_arg) {
while (1) {
a++;
sleep(10);
}
}
int main(void) {
pthread_t t1;
pthread_create(&t1, NULL, thread1_func, (void*)"Thread 1");
sleep(1000);
return 0;
}

// gdb 调试
(gdb) watch a
Hardware watchpoint 1: a
(gdb) r
Starting program: /data/code/cpp/test/gdb_test/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff77c2700 (LWP 28025)]
[Switching to Thread 0x7ffff77c2700 (LWP 28025)]

Thread 2 "main" hit Hardware watchpoint 1: a

Old value = 0
New value = 1
thread1_func (p_arg=0x555555554834) at main_01.cpp:10
10 sleep(10);

如上代码和调试结果,当 a 的值发生变化时,程序就会停下来。也可以使用地址来监测:watch *(int*)0x555555755014

1
2
3
4
(gdb) p &a
$1 = (int *) 0x555555755014 <a>
(gdb) watch *(int*)0x555555755014
Hardware watchpoint 2: *(int*)0x555555755014

2. 设置观察点只针对特定线程生效

使用 watch expr thread threadnum 命令设置观察点只针对特定线程生效,也就是只有编号为 threadnum 的线程改变了变量的值,程序才会停下来。其他编号线程改变变量的值不会让程序停下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(gdb) i threads
Id Target Id Frame
* 1 Thread 0x7ffff7fcc740 (LWP 28904) "main" main () at main_01.cpp:22
2 Thread 0x7ffff77c2700 (LWP 28973) "main" 0x00007ffff78a7680 in __GI___nanosleep (requested_time=requested_time@entry=0x7ffff77c1ea0,
remaining=remaining@entry=0x7ffff77c1ea0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28
3 Thread 0x7ffff6fc1700 (LWP 28974) "main" 0x00007ffff78a7680 in __GI___nanosleep (requested_time=requested_time@entry=0x7ffff6fc0ea0,
remaining=remaining@entry=0x7ffff6fc0ea0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28
(gdb) watch a thread 3
Hardware watchpoint 3: a
(gdb) c
Continuing.
[Switching to Thread 0x7ffff6fc1700 (LWP 28974)]

Thread 3 "main" hit Hardware watchpoint 3: a

Old value = 2
New value = 4
thread2_func (p_arg=0x55555555488d) at main_01.cpp:15
15 sleep(10);

3. 设置读观察点

使用 rwatch 命令设置读观察点,也就是发生读取变量行为时,程序就会停住。

rwatch a 表示每次访问 a 的值就会让程序停下来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// code
int a = 0;
void *thread1_func(void *p_arg) {
while (1) {
a++;
sleep(10);
}
}
void *thread2_func(void *p_arg) {
while (1) {
a++;
sleep(10);
}
}
int main(void) {
pthread_t t1, t2;
pthread_create(&t1, NULL, thread1_func, (void*)"Thread 1");
pthread_create(&t2, NULL, thread2_func, (void*)"Thread 2");
sleep(1000);
return 0;
}

// gdb 调试
(gdb) rwatch a
Hardware read watchpoint 2: a
(gdb) c
Continuing.
[Switching to Thread 0x7ffff6fc1700 (LWP 29502)]

Thread 3 "main" hit Hardware read watchpoint 2: a

Value = 2
0x0000555555554763 in thread2_func (p_arg=0x55555555488d) at main_01.cpp:14
14 a++;

4. 设置读写观察点

使用 awatch 命令设置读写观察点,也就是发生读取变量或改变变量值的行为,程序就会停住。