GDB awatch和rwatch

使用watch设置观察点(watchpoint),可以监测某个变量被修改的情况。除此之外,GDB还提供了awatch和rwatch命令:

(gdb) rwatch num          当要观察的变量num被读时,程序暂停运行
(gdb) awatch num          当要观察的变量num被读或被写,程序暂停运行
(gdb) info watchpoints    查看当前设置的所有观察点

在C语言中,由于语法检查的宽松性,当数组出现越界访问时,程序并不会报错。如下面的程序:

#include <stdio.h>

int main(void)
{
    int a[10] = {0};
    int i = 0;
    for(i = 0; i < 10; i++)
        a[i] = i;

    a[12] = 12;
    printf("a[12] = %d\n", a[12]);

    return 0;
}

我们定义的数组长度为10,但程序中对a[12]进行越界访问,程序运行并不会报错,而且还能正常打印,但这会给程序的安全运行带来一定的隐患,而且这类错误从语法上没有任何问题,还不容易被发觉。

为此,我们可以使用GDB的awatch命令来检测这个错误:当数组出现越界的读或写时,程序暂停执行。

root@ubuntu:/home/gdb# gdb a.out 
(gdb) l
1    #include <stdio.h>
2    
3    int main(void)
4    {
5        int a[10] = {0};
6        int i = 0;
7        for(i = 0; i < 10; i++)
8            a[i] = i;
9    
10        a[12] = 12;
(gdb) b 6
Breakpoint 1 at 0x11ac: file main.c, line 6.
(gdb) r
Starting program: /home/gdb/a.out 

Breakpoint 1, main () at main.c:6
6        int i = 0;
(gdb) awatch a[12]
Hardware access (read/write) watchpoint 2: a[12]
(gdb) c
Continuing.

Hardware access (read/write) watchpoint 2: a[12]

Old value = 0
New value = 12
main () at main.c:11
11        printf("a[12] = %d\n", a[12]);
(gdb) print a[12]
$1 = 12
(gdb)

在设置观察点之前,需要先让程序运行并暂停在某个断点上,然后才可以使用awatch来设置观察点。设置好观察点后,使用continue命令让程序继续运行,当程序运行到第10行,对数组元素a[12]进行访问时,就会触发我们设置的观察点,此时程序暂停运行,我们可以使用print命令来打印数组元素a[12]的值。

如果你只想在a[12]被读时暂停程序,可以使用rwatch命令来设置这个观察点。设置流程和awatch命令是一样的,比较两个命令的运行结果,分析一下这两个命令的区别。

《Linux三剑客》视频教程,从零开始快速掌握Linux开发常用的工具:Git、Makefile、vim、autotools、debug,免费赠送C语言视频教程,C语言项目实战:学生成绩管理系统。详情请点击淘宝链接:Linux三剑客