0.前言
平时我们在Windows操作系统下写代码的时候经常会写出bug,此时必不可少地会使用我们VS编译器的调试工具,而我们在Linux操作系统使用gcc编译器时,出现了bug又应该怎么进行调试呢?接下来让我们一起学习一下Linux调试器—gdb吧!
1.gdb调试
课前需知
① 程序的发布方式有两种,
debug
模式和release
模式,Linux gcc/g++
编译出来的二进制程序,默认是release
模式要使用gdb
调试,必须在源代码生成二进制程序的时候,加上-g
选项②一般情况下,可执行程序文件是交给测试人员在release
模式进行测试或发布给用户使用的产品,是不需要包含调试信息,所以需要我们使用-g
选项加上调试信息。
我们在test.c文件中写的代码如下:
#include<stdio.h>
int AddNum(int num)
{
int sum=0;
for(int i=0;i<=num;i++)
{
sum+=i;
}
return sum;
}
int main()
{
printf("debug begin\n");
int ret=AddNum(100);
printf("%d\n",ret);
printf("debug end\n");
return 0;
}
我们使用的gcc编译编译指令如下:
gcc -o test_debug test.c -std=c99 -g
或者我们创建一个Makefile文件定义如下指令:
test:test.c
gcc -o $@ $^ -std=c99 -g
.PHONY:clean
clean:
rm -rf test_debug
gcc
编译指令中,因为我们在代码中使用了for循环,需要C99
标准库的支持,所以需要加上-std=c99
;-g
选项编译生成调试信息,gdb
工具才可以使用该信息进行调试
从上面可以看出,含调试信息的test_debug
可执行文件比不含调试信息test
可执行程序文件大。
LInux指令:
readelf -S 可执行文件名 | grep -i debug
//查询可执行文件是否包含调试信息
gdb指令
使用yum安装:
yum install gdb -y
gdb使用语法:
gdb 可执行文件名
此时表明我们已经进入了调试状态,请看如下指令:
1.按住
ctrl+d
键或quit(q)
:可以退出gdb
调试
2.
list/l
行号:显示binFile
源代码,一直按l
键接着上次的位置往下列,每次列10行,直到末尾!(使用回车键可以自动调用最近的历史指令)
list/l+源文件名:行号
,多文件的时候科使用
3.
list/l
函数名:列出某个函数的源代码。
4.run(或r)
:从开始连续而非单步执行程序
5.break(b) 行号
:在某一行设置断点
6.
info(或i) break(breakpoints或b)
:查看端点信息。
7.break(或b) 函数名
:在某个函数开头设置断点
8.
delete(或d) breakpoints(或b):
删除所有断点
delete breakpoints n:
删除断点编号为n的断点
9.n 或 next
:单条执行,不进入函数(逐过程执行)
10.
step(或s)
:进入函数调用,逐语句执行
11.continue(或c)
:从当前位置开始连续而非单步执行程序,可以从一个端点处运行到下一个端点处。
12.print(或p)
:打印表达式的值,通过表达式可以修改变量的值或者调用函数
p +变量/地址
:打印变量值/地址值。
13,finish:
执行到当前函数返回,然后挺下来等待命令。
14.info(i) locals
:查看当前栈帧局部变量的值
15.set var+修改的值
:修改变量的值
16.display 变量名
:跟踪查看一个变量,每次停下来都显示它的值
17.undisplay:
取消对先前设置的那些变量的跟踪
18.until X行号
:跳至X行,如果X行为空行,会跳到下一个有效行的位置!
19.disable breakpoints(端点编号):
禁用断点,断点还存在但是端点不起作用了
20.
enable breakpoints:
启用断点
21.
breaktrace(或bt)
:查看各级函数调用及参数,即函数调用堆栈的信息。
2.总结
通过上面的学习,我们可以发现Linux
系统gcc
编译器gdb
调试与windows
系统VS
编译器调试有相似的地方:
指令1:
run---ctrl+F5执行程序
指令2:break---F9打断点
指令3:delete+断点编号---F9+光标指定行数,取消指定行数断点
指令4:delete+break(breakpoints)---ctrl+shift+F9,取消所有断点
指令5:finish---shfit+F11跳出执行当前执行点所处函数的剩余行
指令6:quit---shift+F5取消调试
指令7:next---F10逐过程调试
指令8:step---F11逐语句调试
指令9:display+变量---监视窗口