Data Breakpoint
参考:http://msinilo.pl/blog2/post/p571/
调试器提供的数据断点
硬件观察点:系统会为 GDB 调试器提供少量的寄存器(例如 32 位的 Intel x86 处理器提供有 4 个调试寄存器),每个寄存器都可以作为一个观察点协助 GDB 完成监控任务。
软件观察点:gdb以单步的方式运行程序,每一步都检查被监控的表达式是否发生改变,如果改变了就停下来。
体系结构 | 硬件支持的数据断点数 | 最大字节大小 |
---|---|---|
x86 | 4 | 4 |
X64 | 4 | 8 |
ARM | 1 | 4 |
ARM64 | 2 | 8 |
数据断点在下列情况下无效:
- 将未经调试的进程写入内存位置。
- 在两个或多个进程间共享内存位置。
- 内存位置在内核内更新。 例如,如果内存传递给 32 位 Windows ReadFile 函数,则内存将从内核模式进行更新,因此调试器不会在更新时中断。
- 其中,监视表达式在 32 位硬件上大于 4 字节,在 64 位硬件上大于 8 字节。 这是 x86 体系结构的一个限制。
GDB中的 watch breakpoint 对应于Visual Studio中的data breakpoint。
当程序运行到监控表达式作用域外的区域时,断点会被自动删除。
手动设置数据断点
如果断点会改变程序的行为,就不能用调试器提供的data breakpoint,
GDB
寄存器
rsp 栈顶指针,指向栈顶(不是比栈顶高的那个位置,指向的位置就在栈里面)
rbp
rip 指令指针,指向当前将要执行的命令
查看帮助手册
man gdb (在shell中)查看帮助手册
help [instruction] (在gdb中)查看命令的说明
help (在gdb中)查看命令大全
开始调试
g++ -g [filename.cpp] -o “filename.exe”
编译时带上-g,保留调试信息方便调试
gdb helloworld.exe 启动调试器
run args[0] 运行程序
attach 20829 attach到正在运行的程序
disassemble,layout asm 切换为汇编代码
运行
list 查看源代码
list 10 查看指定位置的源代码
run 运行
continue 继续
ni 单步
si 步入
ni(next) 汇编单步
si(step) 汇编步入
finish 执行到函数尾
查看寄存器、内存、变量的值
查看内存用x,查看变量和寄存器用p
p $rax 查看寄存器存储值
p/x $rax 以十六进制显示rax寄存器的值
i r $esp+0x5c 查看寄存器存储值
x $esp+0x5c 查看内存地址内容
x/10x
x/10s
p &v 查看变量v的地址
p (Class1 ) 0x7fffffffdd80 以Class1解释内存地址0x7fffffffdd80处的值
display 当程序被 GDB 暂停时自动打印某变量的值。
info vtble x 查看变量x的虚函数表
ptype x 查看变量x的结构(x可以是类)
断点
backtrace 查看函数栈
ignore 使一个断点失效n次,格式ignore bnum count,bnum是断点编号,count是失效次数
普通代码断点
b [行号] 设置断点
b *0x121212 设置断点
info break 查看已设置断点
break [函数名] 设置函数起始位置为断点
delete [断点编号] 删除断点
clear [行号] 删除断点
disable[断点编号] 禁用断点
watch breakpoint(内存断点、数据断点、观察断点)
watch 只有当被监控变量(表达式)的值发生改变,程序才会停止运行。
rwatch 只要程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行。只能设置硬件观察点。
awatch 只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行。只能设置硬件观察点。
set can-use-hw-watchpoints 0 强制只设置软件观察点
catch breakpoint(捕捉断点)
http://c.biancheng.net/view/8199.html
当某一事件发生时停止执行,包括抛出异常、加载和卸载动态库等。
info
info frame 查看当前各寄存器的值