GDB调试技巧整理
写在前面
最近工作中在进行C语言主机进程相关的开发工作,相关开发工作不依赖与IDE进行,编译环境和运行环境分离(编译是在独立的编译机上进行,编译产生bin文件之后再拿到运行环境中进行使用)。
好的调试工具对于整个开发过程而言是有着非常重要的意义的,它就像人类的眼睛一样,可以让开发者清楚的了解到程序的运行情况。而对于C语言的调试而言,GDB工具是非常实用的工具,也是非常基础的手段。本文在基于之前网友的整理,并结合自己的认识,进行相关的整理,以期做自我总结,并做到对大家的工作有所帮助。
GDB的基础认识
GDB的主要功能集中在如下四个方面:
- 启动程序
- 使程序在指定的位置断点
- 当程序被停住后,检查程序中所发生的事
- 当程序bug时,修改bug产生的影响,继续测试
GDB的基础命令
程序启动
gdb
<program>
其中program就是程序的可执行文件,默认是当前路径,也可以全路径指定
gdb
<program>
core同时调试运行的程序和core文件,core文件是程序运行异常后coredump的文件
gdb
<program>
<PID>
program代表系统的一个进程,PID是其进程号。这种方式下gdb会自动attach附着上去并进行调试。其中program应该能够在系统的环境变量中搜索到 这个地方需要再确认一下
对于已经进行的进程的调试,我们也可以通过
gdb
<program>
进入程序的gdb调试attach
<PID>
完成调试过程向指定PID的绑定
程序启动信息设置
设置启动参数
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
设置运行环境
设置程序的运行路径: path
<dir>
(可以通过show paths 查看)设置环境变量: set environment varname [=value] (可以通过show environment [varname]查看)
设置工作目录
cd
<dir>
设置程序的输入输出
info terminal 显示你程序用到的终端的模式
使用重定向控制程序输出。如:run > outfile
断点
断点设置的关键词是break,可以缩写为b,后文统一使用缩写
断点的设置
- b
<function>
在指定的函数位置增加断点 - b
<filename>
<linenum>
在指定文件的对应行号增加点 - b +offset / -offset 在当前行号前面/后面offset行增加断点
- b … if 当条件成立时断住,如循环体中设置break if i==100
- b
断点的删除
- clear 删除程序中的所有断点
- clear
<linenum>
删除这行对应的断点 - clear
<function>
删除该函数的断点 - delete
<b_id1 b_id2>
删除指定编号的多个断点
断点的查看
- info break [n] ;n可选,表示断点号
断点的运行
- next
<count>
单步运行, 缩写为n - step
<count>
单步跟踪,如果有函数调用,则进入。 缩写为s - continue 继续运行,所谓为c
- next
程序运行信息查看
查看源程序 此处需要测试一下,反编译出来的代码??
- list
<linenum>
显示行号周围的源码 - list
<function>
显示指定函数的源码
- list
查看运行时数据
- print
<expr>
显示表达式对应的信息 - print
/<f>
<expr>
按照指定的格式输出表达式信息
- print
查看栈信息
- backtrace (或bt) 打印当前的函数调用栈的所有信息
- info args 打印当前函数的参数名及其值
- info locals 打印当前函数的所有局部变量及其值
改变程序的执行
修改变量值
- print var=
<val>
修改变量var的值为val
- print var=
跳转执行
- jump
<linespec>
指定下一条语句的执行点,可以通过filename:linenum的形式,也可以通过+num这种偏移量的形式
- jump
产生信号量
- signal 产生一个信号量给调试的程序
强制函数返回
- return 强制当前函数返回
- return
<expr>
强制当前函数以表达式结果作为返回值返回