GDB再学习:断点调试之数据断点

Posted Stoneshen1211

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDB再学习:断点调试之数据断点相关的知识,希望对你有一定的参考价值。


1 数据断点

当调试程序时,如果发现所定义的一个数据结构中的某一变量总是被意外地改变,查出这类问题的根源并不容易。如果处理器能提供一种功能----当某一变量的值被改动时能自动停下来就好了,这样就可以通过调用栈找到问题的根源。
这就是引入数据断点的目的。数据断点与硬件断点很相似,需要在处理器的寄存器中设置所监视数据变量的内存地址。当被监视的内存单元被修改时处理器将产生中断,调试工具利用这一中断让我们获得检查程序的机会。
与硬件程序断点一样,数据断点的个数也很有限。

以上引用自《专业嵌入式软件开发 全面走向高质高效编程》

2 程序准备

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>

int j = 0;

int test2()
{
	char* s8Buf = NULL;
	
	strcpy(s8Buf, "8888");
	
	return 0;
}

int main()
{
	int i  = 0;
	
	for (i = 0; i < 60; i++)
	{
		j++;
		printf("-------->index %d\\n", i);
		sleep(1);
	}

	test2();
	
	return 0;
}

3 指令介绍

当我们对某个变量使用watch进行监控时候,必须确保这个变量的有效性,即如果对某个局部变量使用watch命令,必须确保程序已经执行在这个变量所在的函数体内。如果是全局变量,则没有这个限制。

3.1 监控变量,使用变量名 watch var

var为变量的名字。

如下,设置监控全局变量j,可以看到,当全局变量的由初始值0变为1的时候,被gdb监控到,并打印出这个全局变量被改变的位置。

(gdb) start
Temporary breakpoint 1 at 0x40058f: file test_gdb.c, line 19.
Starting program: /home/test_demo/gdb/test_gdb 
Temporary breakpoint 1, main () at test_gdb.c:19
19		int i  = 0;
(gdb) 
(gdb) 
(gdb) 
(gdb) watch j
Hardware watchpoint 2: j
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
2       hw watchpoint  keep y                      j
(gdb) continue
Continuing.

Hardware watchpoint 2: j

Old value = 0
New value = 1
main () at test_gdb.c:24
24			printf("-------->index %d\\n", i);
(gdb) 

3.2 监控变量,使用变量地址 watch addr

除了直接使用变量名之外,还可以使用变量名的地址来进行监控。

在下面的例子中,我们首先获取了全局变量j的地址为0x601044,然后再使用watch命令对这个地址进行监控,但是并不是直接使用“watch 0x601044”这种方式,而是需要将地址转换为适当的数据类型。在这个例子中,全局变量j的类型为int,因此需要使用命令“watch *(int *)0x601044”,代表需要监视以地址0x601044为开始,4字节区域的值(假定int为4字节,为啥假定,不同的处理器可能定义不一样)。

(gdb) start
Temporary breakpoint 1 at 0x40058f: file test_gdb.c, line 19.
Starting program: /home/test_demo/gdb/test_gdb 

Temporary breakpoint 1, main () at test_gdb.c:19
19		int i  = 0;
(gdb) print /a &j
$2 = 0x601044 <j>
(gdb) watch *(int *)0x601044
Hardware watchpoint 2: *(int *)0x601044
(gdb) continue
Continuing.

Hardware watchpoint 2: *(int *)0x601044

Old value = 0
New value = 1
main () at test_gdb.c:24
24			printf("-------->index %d\\n", i);
(gdb) 

以上是关于GDB再学习:断点调试之数据断点的主要内容,如果未能解决你的问题,请参考以下文章

GDB再学习:断点调试之事件断点

GDB再学习:断点调试之事件断点

GDB再学习:断点调试之事件断点

GDB再学习:断点调试之软件断点

GDB再学习:断点调试之软件断点

GDB再学习:断点调试之硬断点