安装gdb-10
执行如下命令可在Ubuntu 18.04 LTS系统中安装自带源码高亮功能的gdb-10:
1
2
3
4
5
6
apt install -y software-properties-common
# 若遇到ModuleNotFoundError: No module named 'apt_pkg'问题,只需
# 将/usr/bin/add-apt-repository中的`!/usr/bin/python3`改为`!/usr/bin/python3.6`
add-apt-repository ppa:ubuntu-toolchain-r/test -y
apt update -y
apt install -y gdb
加载调试程序
file:可以使用gdb [可执行文件]直接加载调试二进制文件,也可以先启动gdb再使用file [可执行文件]加载调试目标文件。
设置源码查找路径
set directories:一次设置多个源文件查找路径1
set directories /work/study/jax/:/root/.cache/bazel/_bazel_root/42210d9a2e5c41f7817f753f6f92c412/directory/dir:在源文件查找路径中添加一个路径,若已存在则不会重复添加1
directory /work/study/tensorflow
gdb -d:如果希望在gdb启动时加载代码的位置,可以使用gdb的-d参数1
gdb -q main -d /search/code/some
替换查找源文件的路径
shell readelf <target> -p .debug_str:可以用于查看原来的源码路径set substitute-path:在调试时,如果源代码文件已经被移动到其它目录下,那么可以使用set substitute-path from to命令设置新的路径(to)替换旧的路径(from)1
set substitute-path /work/study/tensorflow /work/Develop/tensorflowunset substitute-path [path]:可用于取消源码路径替换
打印源码
l:打印源码l begin,end:列出begin到end行之间的源码l <file>:<line>:列出指定文件指定行号的源码l <file>:<line1>,<file>:<line2>:列出指定文件指定行号之间的源码l <file>:<func_name>:列出指定文件指定函数的源码
设置源码一次列出行数
set listsize:设置源码一次列出的行数,默认是10行,可以使用该命令进行修改1 2 3
set listsize 20 # 一次列出20行源码 # 若设置为0或者unlimited,则源码列出就无限制
show listsize:查看listsize所设置的大小
设置程序运行参数
存在三种方法指定程序运行的参数,以./main 1 2 3 4为例:
- gdb启动时直接设置程序运行参数,示例:
gdb --args main 1 2 3 4 - gdb中启动程序运行时为程序传递参数,示例:
r 1 2 3 4或者start 1 2 3 4 - gdb中使用
set args设置所调试二进制文件的运行参数,示例:1
set args 1 2 3 4注意: gdb中使用
show args可查看所设置好的运行参数。
设置运行环境变量
set environment/set env可用于在gdb中设置环境变量,示例:1 2
set env LD_LIBRARY_PATH=. # set environment LD_LIBRARY_PATH=.
设置程序的运行路径
path <dir>可用于设定程序的运行路径show paths可用于查看程序的运行路径
设置工作目录
cd <dir>:相当于shell的cd命令,可用于设置工作目录pwd:用于显示当前所在的工作目录
完整打印字符串
set print elements 0:完整打印较长的字符串内容1 2 3
set print elements 0 show print elements # Limit on string chars or array elements to print is unlimited.
gdb日志重定向到文件
set logging可以用于将gdb的输出重定向到某个文件1 2 3 4
set logging file <file name> set logging on info functions set logging off
重定向程序的输入输出
r > outfile < inputfile或者run > outfile < inputfile可用于重定向程序的输入输出
设置观察点
watch:当所watch的变量值发生变化时,程序会停下来1
watch var
启动断点设置
在程序入口处打断点的方法有两种,描述如下:
start:调试可执行文件时若希望启动时即在main函数处停住,则可以使用start启动运行- 说明:
start命令在启动程序运行时会在main函数处设置一个临时断点
- 说明:
- 先使用
info files获取Entry point地址(如0x401050),再使用b *0x401050在入口地址处打断点
设置断点
b <file>:<line>:断点设置在指定文件指定行- 类成员函数设置断点的方法:
- 需加上完整命名空间,写法如
b tensorflow::DirectSession::Run - 若带有匿名命名空间,则需使用
(anonymous namespace)表示匿名命名空间名称,如b tensorflow::(anonymous namespace)::ExecutorState::ScheduleReady(第二个命名空间即为namespace {})
- 需加上完整命名空间,写法如
- 保存已经设置的断点
save breakpoints file-name-to-save保存已设置的断点source file-name-to-save批量加载断点设置
tb用于设置临时断点,用法与b相同,但设置的断点只生效一次ignore bnum count:在设置断点以后,可以忽略断点ignore 1 5:接下来5次编号为1的断点触发都不会让程序中断,只有第6次断点触发才会让程序中断
del bnum: 删除第bnum号断点,del是删除所有断点
设置条件断点
break if:break [break-args] if (condition)可用于设置条件断点1 2 3
break main if argc > 1 break 180 if (str.empty() && i < 0) break test.c:34 if (x & y) == 1
condition:与break if类似, 但condition只能作用于已经存在的断点上,用法:condition <break_list> (condition)1
cond 3 i == 3注意:条件表达式的返回值是
int类型。
查看变量的类型
whatis:查看变量的类型1
whatis var
ptype:查看变量的详细类型信息1
ptype var
查看变量定义所在的文件
i variables:查看定义该变量的文件,gdb会显示匹配名称表达式的所有变量。1 2
i variables var i variables ^var$ # 特定只显示名称为var的变量
info variables不会显示局部变量,即使是static变量所显示的有用信息亦不多。
查看函数调用堆栈
bt/backtrace:查看当前的堆栈信息,堆栈中的每个函数都被分配了一个编号,最近被调用的函数在0号帧中 (栈顶)bt n表示只打印栈顶上n层的栈信息,bt -n:表示只打印栈底下n层的栈信息
f/frame:用于切换当前函数栈f n命令表示在gdb中切换到编号为n的栈帧f命令用于查看当前栈帧的编号、函数名、函数参数值、函数所在文件及行号、函数执行到的语句等信息info f命令用于查看当前栈帧寄存器和参数信息info f n命令用于查看编号为n的栈帧寄存器和参数信息
up/down:也可用于切换栈帧,down n命令表示往栈顶方向下移n层,up n命令表示往栈底方向上移n层
函数调用返回值赋值给gdb变量
set:可以使用set命令将某个函数调用结果赋值给一个gdb变量1 2
set $proto=test_module->ToProto() p $proto
- 使用
set命令可对某个变量进行强制类型转换,示例如下:1 2 3 4 5 6 7
p cos(0.0) # $1 = -1073776640 set $p = (double (*) (double)) cos p cos(0.0) # $2 = -1073776640 p $p(0.0) # $3 = 1
继续执行到下一个断点
c/continue:继续执行程序,直到再次遇到断点处
继续运行到指定位置
u <line>/until <line>:继续执行到<line>行处
跳过执行
skip function <func_name>:step时跳过执行<func_name>函数skip file <file_name>: step时跳过执行<file_name>文件中的所有函数
gdb中使用shell命令
shell <command>:command表示用户即将要执行的shell命令