@TOC
一、gdb的使用
1. 可执行程序的创建
1. mytest.c
vim myetst.c
如果没有创建就会默认创建一个mytest.c文件,并进入vim编辑器
#include<stdio.h> int mysum(int top) { int i=0; int sum=0; for(i=1;i<=99;i++) { sum+=i; } return sum; } int main() { printf("proess begin running ...!\n"); int result =mysum(100); printf("result:%d\n",result); printf("proess end running ...!\n"); return 0; }
这里假设函数是计算1到100的和,结果我们只有1到99的和,所以调试寻找哪里错了。
2. makefile
vim makefile
如果没有创建就会默认创建一个mytest.c文件,并进入vim编辑器
mytest:mytest.c gcc $^ -o $@ .PHONY:clean clean: rm -f mytest
2. gdb 的安装
sudo yum install -y gdb
3.使用gdb的过程
1.进入交互模式
在这里插入图片描述
输入 gdb ,进入gdb对应的交互模式中
出现红框中的内容说明已经进入交互模式。
2.退出交互模式
输入quit,即可退出交互模式
在这里插入图片描述
3. linux默认release版本不可调试
在这里插入图片描述
gdb mytest
//上面定义的就为myetst.c文件输入
gdb mytest
,发现会报错,不是Debug不可以进入调试
1. 将其改成 debug版本
再次使用
vim makefile
,进入 makefile
mytest_d: mytest.c gcc $^ -o $@ -g .PHONY:clean clean: rm -f mytest_d
在原本的基础上,加入了
-g
,使程序以debug版本发布
同时为了与之前产生的release版本的mytest 进行区分,使用myetst_d来代替
2.调试
gdb mytest_d
,将不会报错
在这里插入图片描述
1. l +行数 ——显示代码
输入
l 1
,则从第一行开始显示代码
(gdb) l 1 warning: Source file is more recent than executable. 1 #include<stdio.h> 2 int mysum (int top) 3 { 4 int i=0; 5 int sum=0; 6 for(i=1;i<=99;i++) 7 { 8 sum+=i; 9 } 10 return sum;
若输入
l 9
,则会将第九行的上下文都打印出来
(gdb) l 9 4 int i=0; 5 int sum=0; 6 for(i=1;i<=99;i++) 7 { 8 sum+=i; 9 } 10 return sum; 11 } 12 int main() 13 {
显示完整代码
在这里插入图片描述
gdb 本身具有记忆命令的能力
在输入
l 1
后,再次回车
,就会把将完整代码
显示出来
2. 断点设置 —— b
(gdb)b 行号
——断点设置
相当于VS中的F9
(gdb) b 14 Breakpoint 1 at 0x4005b8: file mytest.c, line 14.
3. 运行 —— r
(gdb)r
——运行,遇到断点就会停止
相当于 VS中F5
(gdb) r Starting program: /home/mydir/test/mytest_d Breakpoint 1, main () at mytest.c:14 14 printf("proess begin running ...!\n");
4. 逐过程——n
(gdb) n
——一行一行往下走
相当于VS中的F10逐过程
(gdb) n proess begin running ...! 15 int result =mysum(100); (gdb) n 16 printf("result:%d\n",result);
输入两次 n后,第十五行语句已经执行完,光标指向第十六行,但第十五行处是一个函数,
说明逐过程不进入函数中
5. 查看断点——info b
(gdb) info b
——查看断点
(gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x00000000004005b8 in main at mytest.c:14 breakpoint already hit 1 time
记住这里的Num所对应的数字,在后面的删除断点要用
6. 删除断点—— d 编号
d 编号
——删除断点
(gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x00000000004005b8 in main at mytest.c:14 breakpoint already hit 1 time (gdb) d 1 (gdb) info b No breakpoints or watchpoints.
查看断点时,
Num所对应的数字就是编号
7. 逐语句——s
(gdb) s
——逐语句
相当于VS中的F11
(gdb) b 15 Breakpoint 4 at 0x4005c2: file mytest.c, line 15. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/mydir/test/mytest_d proess begin running ...! Breakpoint 4, main () at mytest.c:15 15 int result =mysum(100); (gdb) s mysum (top=100) at mytest.c:4 4 int i=0;
再次使用
b设置断点
在函数第十五行处,再次输入r 运行
,由于处于调试过程中,相当于重新开始
,输入 y回到断点处
发现 输入
s
时,可以进入函数中
说明逐语句可以进入函数
8. 监视—— display +常量/地址
(gdb) display 常量/地址
——地址
相当于VS中的监视
6 for(i=1;i<=99;i++) (gdb) display sum 1: sum = 0 (gdb) display i 2: i = 0 (gdb) s 8 sum+=i; 2: i = 1 1: sum = 0 (gdb) s 6 for(i=1;i<=99;i++) 2: i = 1 1: sum = 1
通过不断
s
,使光标处于for循环处,随着光标向下移,sum和i也随之改变
(gdb) display &i 3: &i = (int *) 0x7fffffffe46c (gdb) s 8 sum+=i; 3: &i = (int *) 0x7fffffffe46c 2: i = 2 1: sum = 1 (gdb) s 6 for(i=1;i<=99;i++) 3: &i = (int *) 0x7fffffffe46c 2: i = 2 1: sum = 3
也可以直接监视地址的变化
9.去除监视——undisplay 编号
(gdb) undisplay 编号
——去除监视
(gdb) s 6 for(i=1;i<=99;i++) 3: &i = (int *) 0x7fffffffe46c 2: i = 2 1: sum = 3 (gdb) undisplay 3 (gdb) s 8 sum+=i; 2: i = 3 1: sum = 3 (gdb) display 2 4: 2 = 2 (gdb) s 6 for(i=1;i<=99;i++) 4: 2 = 2 2: i = 3 1: sum = 6
在每次显示sum和i与i
冒号的前面的1 2 3
就为编号
10 跳转至指定行——until 行数
until 行数
——跳转至指定行
(gdb) s 5 int sum=0; (gdb) s 6 for(i=1;i<=99;i++) (gdb) until 10 mysum (top=100) at mytest.c:10 10 return sum;
光标刚开始在第6行的for循环处,until后直接跳出循环
11 .运行至下一个断点处——c
(gdb) c
——运行至下一个断点处
相当于VS中再次使用F5
在这里插入图片描述
有两个断点分别在 6行和8行
在这里插入图片描述
运行后处于第6行的断点处,使用c后,处于第8行的断点处