前面两篇gdb的文章基本上已经介绍的差不多了,但是还有一些可以提高调试效率的方式需要介绍一下。
1.调试宏定义
如果gcc只是-g选项,那么宏定义是不能被调试的,-g是有等级的,需要使用-gdwarf-2 -g3才可以调试宏定义
如果宏定义只是普通的数值替换 通过p 宏定义就可以打印出值
如果宏定义是一系列语句的组合,可通过macro expand 宏定义 把对应的宏语句打印出来,宏定义里的参数可以是任意参数
2.调试coredump
程序运行可能由于段错误导致运行失败,为了定位到错误需要查看程序运行的错误状态
首先需要让程序可以生成core文件,输入命令 ulimit -c ,如果输出是0表示不会生成core文件
通过命令 ulimit -c unlimited 即可产生core文件
gdb core文件即可查看程序错误信息
3.测试函数
gdb可以直接执行函数并传递参数查看结果,而且不影响原有程序,非常适合单元测试
但是如果函数内有全局变量并且被修改,那么不建议使用,因为会改变全局变量的值
通过 call <函数名>(函数参数) 即可查看函数返回值
假如函数参数是一个复杂的结构体,需要用特殊方式构造参数
通过 set $temp = ({SOME_TYPE *}malloc(sizeof(SOME_TYPE))) 开辟临时空间,启动SOME_TYPE可以是struct union enum
通过 set $temp->成员 = 1 这种方式填充数据
call <函数名>($temp) 即可查看结果
4.函数桩
假设函数的返回值我们临时想改变,可以在被调试的函数内直接 return value 即可改变原有函数的返回值
5.gdb打印信息不全
有时候打印的数据太长gdb会用...省略后面的数据
通过命令 set print elements 0 即可显示全部信息
6.tui界面
gdb可以使用tui界面,边看代码边调试,毕竟list命令不方便
进入tui界面一种是gdb -tui <可执行程序>
另一种是gdb <可执行程序>后 输入 ctrl + x 和 ctrl + a,退出是同样的命令
tui界面如果经常数据会导致界面混乱,可以通过ctrl + l 刷新界面
在tui界面方向键不能查看历史命令,需要使用ctrl p/n 往回/往前查看历史命令
移动光标通过 ctrl b/f 往左/往右移动
tui查看汇编可以通过 layout asm
返回源码通过 layout src
tui可以同时查看源码和汇编,通过命令ctrl + x 和 数字2,注意数字2没有ctrl
如果想恢复成1个窗口,通过命令ctrl+x 和数字1