安装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/tensorflow
unset 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命令