使用GDB进行断点调试
1.断点类型
软件断点:由非法指令异常实现(软件实现)
硬件断点:由硬件特性实现(数量有限)
数据断点:由硬件特性实现(数量有限)
为什么要分软件断点和硬件断点呢?
软件断点通常是可以运行于内存中的程序,代码加载到内存中执行,那么软件断点就是有效的。
对于flash中的程序执行,软件断点就没有用了。此时必须依赖于硬件断点。
这就是软件断点和硬件断点使用上的不同。
软件断点:适用于运行于内存中的程序
硬件断点:适用于直接在flash中运行的程序。
数据断点:往往用来监视一段内存的,如果这段内存被访问了(读或写),程序的执行立即停下来,这就是数据断点。
2.软件断点的相关操作
—通过函数名设置断点
break func_name [if var = value]
tbreak func_name [if var = value]
break和tbreak的差异:断点有效次数的差异
break设置的断点总是有效的(永久断点)
tbreak设置一次有效断点(一次性断点)
[if var = value],如果在打断点的时候,指明了这样的条件,那么该断点就变成了一个条件断点。条件断点只有在条件成立时,才能暂停程序的执行。
—通过文件名行号设置断点
break file_name : line_num [if var = value]
cbreak file_name : line_num [if var = value]
操作 命令
断点查看 info breakpoints
断点删除 delete 1 2 n
delete breakpoints 删除所有断点
断点状态改变 enable 1 2 n
enable breakpoints
disable 1 2 n
disable breakpoints
3.调试中常用的操作
操作 命令
变量查看 print name
变量设置 set var name = value
执行下一行代码 next
连续执行n行代码 next n
执行进入函数 step
强制当前函数返回 return [value] 以某个值返回当前函数
运行至当前函数返回 finish 执行完当前所在的函数,然后暂停下来
执行至目标行 until line
跳转执行 jump line
3.硬件断点及其应用
—当代码位于只读存储器(flash)时,只能通过硬件断点调试
—硬件断点需要硬件支持,数量有限
—GDB中通过hbreak命令支持硬件断点
—hbreak和break的使用方式完全一致
举个例子:
void func()
{
*g_pointer = (int)"D.T.Software";
}
如果发现这段代码有问题,会怎么做呢?
会直接修改代码,然后编译。这样看起来可以,那有没有更高效的办法呢?
如何验证,究竟是不是这行代码引起的?(不通过重新修改代码,然后编译的手段)
可以通过GDB来验证解决方案,而不是直接修改代码。此时硬件断点就出场了。
gdb test.out
start
//查看当前的gdb支持几个硬件断点
show can-use-hw-watchpoints
hreak func
info breakpoints
continue
print g_pointer
set var g_pointer = (int*)malloc(sizeof(int));
print g_pointer
continue
gdb的高效之处,就是在定位的过程中,不需要去修改源代码,自然就不需要进行重新编译。
小结:
GDB是GNU项目中的调试器,能够跟踪或改变程序的执行;
GDB能够根据core dump回溯检查导致程序异常结束的原因;
GDB同时支持软件断点、硬件断点和数据断点;
GDB是嵌入式开发中必须掌握的重要工具。