系列文章目录

GDB再学习(1):前言GDB再学习(2):编译GDB再学习(3):GDB的启动和运行GDB再学习(4):程序准备GDB再学习(5):常用指令介绍GDB再学习(5.1):常用指令介绍_print/display_查看变量或寄存器中的值GDB再学习(5.2):常用指令介绍_examine_查看内存区域的数值GDB再学习(5.3):常用指令介绍_backtrace_查看函数栈GDB再学习(5.4):常用指令介绍_ptype/whatis_查看程序符号表GDB再学习(6):断点调试之软件断点GDB再学习(7):断点调试之硬断点GDB再学习(8):断点调试之数据断点GDB再学习(9):断点调试之事件断点GDB再学习(10):线程调试相关GDB再学习(11):如何生成Core文件GDB再学习(12):gdb server的使用



文章目录

  • 系列文章目录
  • 1 数据断点
  • 2 程序准备
  • 3 指令介绍
  • 3.1 监控变量,使用变量名 watch var
  • 3.2 监控变量,使用变量地址 watch addr



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)