gdb调试中设置监控点watch,rwatch,awatch的区别及说明
作者:凌肖战
一. watch 命令的两种监控机制
在 gdb 调试中,
watch 命令有两种设置观察点的方式:
- 硬件观察点
- 软件观察点
注意:
而 awatch 和 rwatch 命令只能设置硬件观察点。
watch 命令所支持的两种设置机制
软件观察点:
所谓软件观点(software watchpoint),即用 watch 命令监控目标变量(表达式)后,GDB 调试器会以单步执行的方式运行程序,并且每行代码执行完毕后,都会检测该目标变量(表达式)的值是否发生改变,如果改变则程序执行停止。
可想而知,设置软件观察点的方式,一定程度上会影响程序的执行效率。但从另一个角度看,调试程序的目的并非是为了获得运行结果,而是查找导致程序异常或 Bug 的代码,因此即便软件观察点会影响执行效率,一定程度上也是可以接受的。
硬件观察点:
所谓硬件观察点(Hardware watchpoint),和前者最大的不同是,它在实现监控机制的同时不影响程序的执行效率。
简单的理解,系统会为 gdb 调试器提供少量的寄存器(例如, 32 位的 Intel x86 处理器提供有 4 个调试寄存器),每个寄存器都可以作为一个观察点协助 gdb调试器完成监控任务。
需要注意的是,基于寄存器个数的限制,如果调试环境中设立的硬件观察点太多,则有些可能会失去作用,这种情况下,
gdb 调试器会发出如下警告:
Hardware watchpoint num: Could not insert watchpoint
除此之外,受到寄存器数量的限制,可能会出现:无法使用硬件观察点监控数据类型占用字节数较多的变量(表达式)。
例如,某些操作系统中,gdb 调试器最多只能监控 4 个字节长度的数据,这意味着 C、C++ 中 double 类型的数据是无法使用硬件观察点监测的。
这种情况下,可以考虑将其换成占用字符串少的 float 类型。
目前,大多数 PowerPC 或者基于 x86 的操作系统,都支持采用硬件观点。
并且 gdb 调试器在建立观察断点时,会优先尝试建立硬件观察点,只有当前环境不支持硬件观察点时,才会建立软件观察点。
借助如下指令,即可强制 gdb 调试器只建立软件观察点:
set can-use-hw-watchpoints 0
注意,在执行此命令之前建立的硬件观察点,不会受此命令的影响。
awatch 命令和 rwatch 命令只能设置硬件观察点,如果系统不支持或者借助如上命令禁用,
则 GDB 调试器会打印如下信息:
Expression cannot be implemented with read/access watchpoint.
二. watch 命令,rwatch 命令,awatch 命令的区别
1. watch 命令可以设置硬件观察点方式或软件观察点的方式。而 rwatch 命令与 awatch 命令只能设置硬件观察点的方式。
2. 每个命令的功能不同。
- watch 命令,即变量(或表达式)的值改变,程序都会停下来。
- rwatch 命令,即当发生读取变量行为时,程序就会暂停住。
- awatch 命令,即当发生读取变量或改变变量值的行为时,程序就会暂停住。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。