系列文章目录
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)