文章目录
Linux-开发与管理 P3 GDB调试器
GDB简介
Linux的大部分特色源自于Shell的GNU调试器,也称作GDB
GDB简单地说就是一个调试工具,它是一个受通用公共许可证(GPL)保护的自由软件
GDB可以让用户查看程序的内部结构、打印变量值、设置断点,以及单步调试源代码。它是功能极其强大的工具,适用于修复程序代码中的问题
GDB使用流程
再具体了解GDB命令前,首先需一个可以拿来测试程序,然后在简单演示一下整体调试的流程
首先创建程序如下
#include <stdio.h>
int my_add(int a,int b){
int s;
s = a+b;
return s;
}
int my_sub(int a,int b){
int s;
s = a-b;
return s;
}
int main(int argc, const char *argv[])
{
int x = 100,y = 50;
int s1,s2;
s1 = my_add(x,y);
s2 = my_sub(x,y);
printf("x + y = %d\nx - y = %d\n",s1,s2);
return 0;
}
是一个简单的加减函数调用实例,然后对其进行GCC编译,当然这里要加上-g,以便在后面进行GDB调试
gcc -g gdb_test.c -o gdb_test
没有错误,也能够进行正常的输出结果,接下来就来进入GDB调试模式
这样就成功进入到了GDB调试模式,这里可以看到各种有关的信息,当然这里可以不用管它用到在说,最后面会看到一个(gdb),可以在后面输入GDB指令,这里输入第一个指令,也就是help指令(关于help会在后面详细介绍)
可以看到所有的指令的分类帮助界面
查看文件
接下来,可以对进行GDB调试的程序进行内容查看
这里输入list(简写为l)就可以进行程序内容的查看
断点
然后就可以对程序进行断点设置,设置断点能够让程序在调试的时候停下来的地方,方便对各种信息和变量进行查看
这里先是由断点的命令之一break (后面会详细讲解断点指令)
这样就成功对主函数main、加子函数my_add和减子函数my_sub的开始分别设置了一个断点
当然可以通过info breakpoints [n]来查看所有或者指定断点内容
这里来查看一下所有刚才设置的断点简写为info b
运行
好的,设置完断点之后,最后就是来运行程序进行调试
运行的命令时run(简写为r)
好的现在就来到了第一个断点,如果没有设置断点程序将会直接全部进行直到程序结束,但是这里设置了断点,所以需要continue来继续程序的执行
好的,现在来到了my_add函数的开始代码段处,这里可以继续输入continue,或者可以查看当前程序运行状况时的变量值,查看变量值可以通过p 变量名来查看
这里对所有的变量的情况进行了一个查看,然后继续运行程序
直到最后程序运行结束
好的这就是一个简单的GDB调试的工作流程,关于每个流程里涉及到的命令在后面会给大家详细讲解,这里给讲解最后一个使用的命令quit(简写为q)用来退出GDB调试模式
GDB参数与基本命令
基本命令
help命令
命令 | 功能 |
---|---|
help | 列出GDB帮助信息 |
help topic | 列出相关话题中的GDB命令 |
help command | 流出命令描述信息 |
apropos search-word | 搜索相关的话题 |
info命令
命令 | 功能 |
---|---|
info argsi args | 列出运行程序的命令行参数 |
info breakpoints | 列出断点 |
info break | 列出断点号 |
info break breakpoint-number | 列出指定断点的信息 |
info watchpoints | 列出观察点 |
info registers | 列出使用的寄存器 |
info threads | 列出当前的线程 |
info set | 列出可以设置的选项 |
断点命令
break命令
命令 | 功能 |
---|---|
break function | 在指定的函数处设置断点 |
break line-number | 在指定的行号处设置断点 |
break +offset | 在当前停留的地方后面的几行处设置断点 |
break -offset | 在当前停留的地方前面的几行处设置断点 |
break file:func | 在指定的file文件中的func处设置断点 |
break file:nth | 在指定的file文件中的第nth行设置断点 |
break *address | 在指定的地址处设置断点 |
break line-number if condition | 如果满足条件,在指定位置设置断点 |
break line thread thread-number | 在指定的线程中中断,使用info threads可以显示线程号 |
tbreak | 设置临时的断点,中断一次后断点会被删除 |
watch condition | 当条件满足是设置观察点 |
clear和delete
命令 | 功能 |
---|---|
clear | 清除所有断点 |
clear func | 清除指定函数处断点 |
clear nth | 清除第n行断点 |
delete(d) | 删除所有断点或观察点 |
delete breakpoint-number | 删除指定断点 |
delete range | 删除指定观察点 |
enable命令
命令 | 功能 |
---|---|
disable breakpoint-number-or-range | 将断点和观察点设置为无效 |
enable breakpoint-number-or-range | 将断点和观察点设置为有效 |
enable oncebreakpoint-number | 设置指定断点有效,当到达断点时置位无效 |
enable delbreakpoint-number | 设置断点有效,当到达断点时删除它 |
finish | 继续执行到函数结束 |
单步运行相关指令
命令 | 功能 |
---|---|
step(s) | 进入下一行代码的执行,会进入函数内容 |
number-of-steps-to-perform | 进入下一行代码的执行,会进入函数内部 |
next(n) | 执行下一行代码 |
next number | 执行指定后的行数的内容 |
until line-number | 继续运行直到到达指定行号,或者函数、地址等 |
return expression | 弹出选中的栈帧 |
stepi(si) | 执行下一条汇编/CPU指令 |
nexti(ni) | 执行下一条汇编/CPU指令 |
info signals info handle handle SIGNAL-NAMEoption | 当收到信号时执行下列动作 |
where | 显示当前的行号和所处的函数 |
堆栈命令
backtrace命令
命令 | 功能 |
---|---|
backtrace(bt) | 显示当前堆栈的追踪,当前所在的函数 |
bt inner-function-nesting-depth | 显示当前堆栈的追踪,当前所在的函数 |
bt -outer-function-nesting-depth | 显示当前堆栈的追踪,当前所在的函数 |
backtrace full | 打印所有局部变量的值 |
list相关命令
命令 | 功能 |
---|---|
lisst(l) | 列出相应的源代码 |
list line-number | 列出相应的源代码 |
list function | 列出相应的源代码 |
list start#,end# | 列出相应的源代码 |
list filename:function | 列出相应的源代码 |
set listsize count | 设置list命令打印源代码时的行数 |
show listsize | 在源代码路径前添加指定的目录 |
directory directory-name | 在源代码路径前添加指定的目录 |
dir directory-name show | 在源代码路径前添加指定的目录 |
directories | 在源代码路径前添加指定的目录 |
directory | 当后面没有参数时,清除源代码目录 |
其他指令
命令 | 功能 |
---|---|
frame number(f number) | 选择指定的栈帧 |
up number | 向上移动指定个数的栈帧 |
down number | 向下移动指定个数的栈帧 |
info frame addr | 描述选中的栈帧 |
info args | 显示选中栈帧的参数 |
info all-reg | 显示选中的局部变量 |
info locals | 显示选中的局部变量 |
info catch | 显示选中的异常处理函数 |
变量命令
print命令
命令 | 功能 |
---|---|
print variable(p variable) | 打印指定变量的值 |
p * array-var@length | 打印array-var中的前length项 |
p/x var | 以十六进制打印整数变量var |
p/d var | 把变量var当作有符号整数打印 |
p/u var | 把变量var作为无符号整数打印 |
p/o var | 把变量var作为八进制数打印 |
p/t var | 以整数二进制的形式打印var变量的值 |
x/b address | 以整数二进制的形式打印var变量的值 |
p/c var | 当字符打印 |
p/f var | 以浮点数格式打印变量var |
p/a var | 打印十六进制形式的地址 |
x/w address | 打印指定的地址,以四字节一组的方式 |
call expressem | 类似于print,但不打印void |
disassem addr | 对指定地址中的指令进行反汇编 |
set命令
命令 | 功能 |
---|---|
set print array on | 以可读形式打印数组,设置为on |
set print array off | 以可读形式打印数组,设置为off |
show print array | 显示以可读形式打印数组 |
set gdb-optionvalue | 设置GDB的选项 |
set print array-indexes on | 打印数组元素的下标,设置为on |
set print array-indexes off | 打印数组元素的下标,设置为off |
show print array-indexes | 显示打印数组元素的下标 |
set print pretty on | 格式化打印C结构体的输出,设置为on |
set print pretty off | 格式化打印C结构体的输出,设置为off |
show print pretty | 显示格式化打印C结构体的输出 |
set print union on | 打印C中的联合体,设置为on |
set print union off | 打印C中的联合体,设置为off |
show print union | 显示C中的联合体 |
set print demangle on | 控制C++中名字的打印,设置为on |
set print demangle off | 控制C++中名字的打印,设置为off |
show print demangle | 显示控制C++中名字的打印 |
文件命令
命令 | 功能 |
---|---|
info files | 列出当前的文件、共享库 |
file file | 把file当作调试的程序 |
core file | 把file当作core文件 |
exec file | 把file当作执行程序 |
symbol file | 从file中读取符号表 |
load file | 动态链入file文件,并读取它的符号表 |
path directory | 把目录directory加入到搜索可执行文件和符号文件的路径中 |
程序命令
命令 | 功能 |
---|---|
run® | 从头开始执行程序,也允许进行重定向 |
continue© | 继续执行直到下一个断点或观察点 |
continue number | 继续执行,但会忽略当前的断点number次 |
kill | 停止程序执行 |
quit(q) | 退出GDB调试器 |