示例代码:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int g_var = 0;
void* thread_func(void* args)
{
sleep(5);
g_var = 1;
}
int main()
{
int i = 0;
pthread_t tid = 0;
pthread_create(&tid, NULL, thread_func, NULL);
for(i=0; i<10; i++)
{
printf("g_var = %d\n", g_var);
sleep(1);
}
}
输出结果:
Bakuman@Shaw-vm:~/workspace$ gcc -lpthread watch.c -o test.out
Bakuman@Shaw-vm:~/workspace$ ./test.out
g_var = 0
g_var = 0
g_var = 0
g_var = 0
g_var = 0
g_var = 1 < —————-这里g_var的值发生改变了
g_var = 1
g_var = 1
g_var = 1
g_var = 1
我代码我们可以发现,g_var变量是一个多线程共享的资源。这意味着除了main函数外,thread_func线程也对g_var变量进行了修改。这是我们不能接受的。
并且这种问题,编译器并不能发现,单靠人工查找是很难发现问题的,所以我们需要借助GDB调试工具来发现问题。
问题:我们如何通过GDB来发现这个问题呢?
数据断点
- GDB中支持数据断点的设置
- watch命令用于监视变量是否被改变(本质为硬件断点)
- watch命令的用法:watch var_name
示例操作:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file test.out
Reading symbols from /home/delphi/workspace/test.out...done.
(gdb) watch g_var <------------------------------监视辩论
Watchpoint 1: g_var
(gdb) start
Temporary breakpoint 2 at 0x80484ab: file watch.c, line 16.
Starting program: /home/delphi/workspace/test.out
[Thread debugging using libthread_db enabled]
Temporary breakpoint 2, main () at watch.c:16
16 int i = 0;
(gdb) print g_var
$1 = 0
(gdb) continue
Continuing.
[New Thread 0xb7feeb70 (LWP 9121)]
g_var = 0
g_var = 0
g_var = 0
g_var = 0
g_var = 0
[Switching to Thread 0xb7feeb70 (LWP 9121)]
Hardware watchpoint 1: g_var
Old value = 0
New value = 1
thread_func (args=0x0) at watch.c:12 < ------ g_var的值在代码这个位置发生变化
12 }