gdb调试技术
-
编译时需要编译为调试模式,否则无法调试
-
命令行编译:
g++ -g test.cpp -o test
需要加上-g参数 -
CMakeLists.txt:
set(CMAKE_BUILD_TYPE "Debug")
或cmake .. -DCMAKE_BUILD_TYPE="Debug"
-
readelf test | grep -i debug 查看是否有调试符号
-
也可以通过gdb test 运行是否有No debugging symbols found in test等输出信息
-
-
开始调试
- gdb test
- gdb test core,用gdb同时调试一个运行程序和core文件
- gdb attach pid_number: 也可以对服务的pid进行attach调试;
- 运行: run,或者直接执行gdb后,使用file test再run;
-
运行时参数
- –args: gdb --args test “hello” 20 true
- 在执行gdb test后,使用set args “hello” 20 true达到同样效果
- show args: 查看命令列参数
-
运行环境
- path或show paths: 查看当前环境的path变量值
- set environment varName[=value]: 设置环境变量
- show environment varName: 查看环境变量
-
查看工作目录
- cd : 相当于执行shell cd命令,跳转到$HOME目录;
- pwd: 显示当前所在的目录;
- gdb -cd ./demo test: 加上-cd选项,命令行指定指定工作目录,执行该命令后,pwd显示为./demo目录
-
程序的输入输出
- 将程序的运行结果输出到文件: run >test.log,运行时重定向到文件中;
-
断点设置
-
break lineNumber: 在当前文件指定行设置断点
-
break function:在当前文件指定函数设置断点,c++中key使用
class::function或function(type,type)格式来指定函数名称
-
break filename:lineNumber
-
break filename:function
-
break [args] if [cond]: 当【cond】这个运算为真时,设置中断点,args可以能是以上
任意一种形式;
-
rbreak regex: 使用正则表达式来寻找可能的函数,并在其进入点设置中断点;
-
break *address: 在程序运行的内存地址设置断点;
-
info break [n]: 查看断点信息, n表示断点号;
-
-
设置观察点
- watch expr: 用于观察变量或表达式值得变化,变化时就停住程序;
- rwatch expr: 当表达式值或变量被读取时,停住程序
- awatch expr:当表达式的值或变量被读取或被写时,停住程序
- info watchpoints:查看所有的观察点;
-
设置捕捉点(catchPoint)
- 可以设置捕捉点来捕捉程序运行时的一些事件。如载入共享库(动态链接库)或 是c++的异常。
- 设置捕捉点格式:catch event,当event发生时,event可以是下面的内容
- throw: 一个c++抛出的异常;
- catch:一个C++捕捉到的异常;
- exec、for、vfork等系统调用(hp-ux系统有用)和load(载入共享库)
- tcatch event:只设置一次捕捉点,当停住以后,应点被自动删除;
-
维护停止点
- clear: 可以跟[文件名]行号或函数名,若未指定,则清除所有断点;
- delete: 同clear;
- disable [breakpoints]: 禁用指定的停止点,若未指定,则停用所以的断点
- enable [breakpoints]: 启用指定停止点,若未指定,则启用所以的断点;
- enable [breakpoints] once range: 所指定的停止点一次,当程序停止后,该停止点马上被gdb自动disable
- enable [breakpoints] delete range:所指定的停止点一次,当程序停止后,该停止点马上被gdb自动删除
-
断点菜单
-
break function: 若function重名或调用多次的话,则会列举出所有的
可能出现的详细位置,0-表示取消,1-表示所有设置断点,其他则设置相应的
断点,比如2 4 6;
-
-
恢复运行和单步调试
- continue©:继续执行直到下一个断点;
- step(s):单步跟踪,若是函数调用,则会进入该函数;进入函数前提是该函数被编译有debug信息;
- next(n):同样单步跟踪,若是函数调用,则不会进入该函数;
- set step-mode on: 打开step-mode模式,于是在进行单步跟踪时程序不会因为没有debug信息而不停住;有利于查看机器码
- finish: 运行程序,直到当前函数完成返回,并打印函数返回值和参数等信息;
- until(u): 执行一行程序,若此时程序是在for、while、do等循环最后一行,则一直执行到循环结束后的第一行程序后停止;
-
信号
- gdb有能力在你调试程序的时候处理任何一种信号,你可以告诉gdb需要处理哪一种信息,你可以要求gdb收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试,handle命令来完成这一功能
- handle signal keyworlds
- nostop
- stop
- noprint
- pass
- noignore
- nopass
- ignore
- info signals
- info handle
-
线程
- break linespec thread threadno: 程序是多线程,则可以定义断点是否在所有的线程上,
或是在某个特定的线程,break linespec thread threadno if expr
-
查看栈信息
-
backtrace(bt)
-
frame(f) n:切换栈
-
up n: 表示栈的上面移动n层,n可以省略,表示向上移动一层
-
down n:表示栈的下面移动n层,n可以省略,表示向下移动一层
-
info args: 打印当前函数参数及其值;
-
info locals: 打印当前函数中所有局部变量及其值;
-
info catch: 打印出当前函数中的异常处理信息;
-
-
查看源程序
- list: 显示当前行后面的源程序;
- list -: 当前行前面的源程序;
- list lineNumber: 显示程序的第Number行周围的源程序;
- list function: 线程函数名为function的函数的源程序;
- set listsize count: 设置一次显示源代码函数,默认是当前行的上、下5行;
- show listsize: 查看当前listsize的设置;
- list fist last: 显示区间直接的源代码;
- list , last: 显示当前行到last之间源代码;
- list fist,:显示first到当前行源代码;
-
搜索源代码
- forward-search(search) regexp: 向后搜索源代码
- reverse-search regexp: 向前搜索;
-
源代码的内存
- info line :命令来查看源代码的内存中的地址,info line后面可以根行号、函数名、文件名:行号、文件名:函数名;
- disassembler [func]: 查看源程序或函数当前执行时的机器码,会把目前内存中的指令dump出来
-
查看运行时的数据
- print (简写p)或同义命令inspect: 查看当前程序运行的数据
- print /: 输出格式,比如print /x i: 将变量i以16进制打印出来;