gdb 内存断点watch 的使用
本文介绍了调试工具中watch命令的使用方法及注意事项。watch可用于监控变量变化,支持整型变量、指针类型和数组/内存区间。指针监控需区分地址本身和地址内容,数组监控会消耗较多CPU资源。局部变量的watch会在变量失效后自动删除。通过示例程序演示了内存断点的使用,展示了mem数组被逐个字节写入的过程。同时指出硬件断点数量受CPU限制(测试支持32个),建议大结构监控时直接指定变量地址以提高效率
1. watch 变量的类型
a. 整形变量: int i; watch i;
b. 指针类型: char *p; watch p, watch *p;
它们是有区别的.
watch p 是查看 *(&p), 是p 变量本身。
watch (*p) 是 p 所指的内存的内容,。
有时候观察的是地址所指内容,有时候是地址本身,虽然这个地址具体位置只有编译器知道。
c. watch 一个数组或内存区间
char buf[128], watch buf,
是对buf 的128个数据进行了监视. 此时不是采用硬件断点,而是软中断实现的。
软中断方式去检查内存变量是比较耗费cpu资源的。
精确的指明地址是硬件中断。
2. 当你设置的观察点是一个局部变量时。局部变量无效后,观察点无效
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
3. 附上一个简单程序方便你利用内存断点观察,调试.
$ cat test.cpp
#include <stdio.h>
#include <string.h>
void initBuf(char *buf);
void prtBuf(char *buf);
char mem[8];
char buf[128];
int main()
{
initBuf(buf);
prtBuf(buf);
return 0;
}
void initBuf(char *pBuf)
{
int i, j;
mem[0]='0';
mem[1]='1';
mem[2]='2';
mem[3]='3';
mem[4]='4';
mem[5]='5';
mem[6]='6';
mem[7]='7';
//ascii table first 32 is not printable
for(i=2;i<8;i++)
{
for(j=0;j<16;j++)
pBuf[i*16+j]=i*16+j;
}
}
void prtBuf(char *pBuf)
{
int i, j;
for(i=2;i<8;i++)
{
for(j=0;j<16;j++)
printf("%c ", pBuf[i*16+j]);
printf("\n");
}
}
玩弄内存调试于股掌之中。
(由于效率问题你需要适当控制内存断点设置,当然,对这个小程序无所谓.)
----------------------------------------
看一下mem 数组, 内存数据是怎样被写入的。
----------------------------------------
gdb test
b main
watch mem
run
Breakpoint 1, main () at test.cpp:9
gdb) continue
Continuing.
Hardware watchpoint 2: mem
Old value = "\000\000\000\000\000\000\000"
New value = "0\000\000\000\000\000\000"
initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:18
(gdb) continue
Continuing.
Hardware watchpoint 2: mem
Old value = "0\000\000\000\000\000\000"
New value = "01\000\000\000\000\000"
initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:19
(gdb) continue
Continuing.
Hardware watchpoint 2: mem
Old value = "01\000\000\000\000\000"
New value = "012\000\000\000\000"
initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:20
(gdb)
......
(gdb) continue
Continuing.
Hardware watchpoint 2: mem
Old value = "0123456"
New value = "01234567"
initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:26
使用watch时出现错误:
----------------------------------------
Could not insert hardware breakpoints: You may have requested too many hardware breakpoints/watchpoints.
你watch的变量超过了硬件能监控的范围。
原因1:
你设置的watchpoints数量过多,系统支持的硬件断点看cpu的能力, 我的cpu16核(8核*2线程), 实测硬件断点数32个, 软件断点当然就支持更多了.
原因2:
你监控一个结构/类成员也可能出现这个问题。因为结构太大了.尽管你只是监控了其中一个变量,但gdb按整个结构算.
解决方法:
----------------------------------------
直接获取你所要监控变量的地址, 监控这个地址.
例如: 监视一个4byte 的整形地址. 书写格式举例如下.
watch *(int*)0x12345678
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐


所有评论(0)