Linux gdb调试C语言程序
gdb常用命令gdb在命令的首字母唯一时是可以缩写的。b/break 函数名:给函数设置断点。c/continue:继续执行。b/break 文件名.c:行号:在指定文件的指定行设置断点。next:单步执行程序,如果是函数则将函数整体执行,不会进入。回车键:执行上次的命令。file 可执行文件名:调试指定的文件。s/step:单步执行程序,如果是函数则会进入。l/list:显示当前行下面的10行代
gdb常用命令
gdb在命令的首字母唯一时是可以缩写的。
-
b/break 函数名
:给函数设置断点。 -
c/continue
:继续执行。 -
b/break 文件名.c:行号
:在指定文件的指定行设置断点。 -
next
:单步执行程序,如果是函数则将函数整体执行,不会进入。 -
回车键
:执行上次的命令。 -
file 可执行文件名
:调试指定的文件。 -
s/step
:单步执行程序,如果是函数则会进入。 -
l/list
:显示当前行下面的10行代码。 -
p/print 变量名
:查看变量的值。也可以查看函数的值(地址)。 -
i/info b/break
:查询断点信息。 -
d/delete
:删除所有的断点。 -
d/delete 断点序号
:删除第几个断点。 -
attach pid
:调试运行中的进程id为pid的程序。
demo1
#include <stdio.h>
int add(int num1, int num2){
return num1 + num2;
}
int main(){
int a = 5;
int b = 8;
int ret = add(a,b);
printf("%d + %d = %d\n", a, b, ret);
return 0;
}
生成可执行文件
调试
选中编译文件
调试必须在编译时加入 -g
,然后再输入file 可执行文件名
,编译时如果没有指定文件名,默认是a.out
。
查看代码
每次l
命令只能看10行。
运行代码
设置断点(函数)
-
先在
add
函数处添加了断点,然后直接运行程序。 -
然后就停在了第4行(实际上是从第10行调用的),也就是
add
中return的位置。
-
执行
n
指令,继续走一步,来到第五行。 -
再次执行
n
指令,也就是ret
赋值完毕,来到第11行。 -
按下
回车
,执行上一次的指令,也就是n
,执行printf
语句打印出信息,显示了下一行的语句:return 0;
打印变量信息
断点情况
- 查看断点
- 删除指定断点
只有一个断点,删除了一号断点
后,就没有断点了。
demo2
#include <stdio.h>
#include <unistd.h>
void printHello(int times){
printf("Hello -- %d\n", times);
}
int main(){
for(int i=0;i<10000;i++){
printHello(i);
sleep(3); // 睡眠3秒
}
return 0;
}
生成可执行文件
for循环如果报错,要加一个-std=c99
。
-o
可以指定可执行程序的名称,这里我将demo2.c
的可执行文件名称指定为demo2
。
测试一下:
如果打印操作不是通过
printHello
函数,并且printf中没有\n
,那么是没有打印结果的。
需要加上\n
,或者是fflush(stdout);
刷新一下缓冲区。
这是因为printf的输出结果被放在缓冲区,如果没有换行符或者刷新缓冲区,不会有输出。
调试
这次我们要调试运行中的程序,所以要获取该程序的进程id
。
ps -ef | grep 进程名
先运行程序,然后从另一个终端中搜索该程序的进程号:
这里的10237
就是PID(process identity)
调试运行中的程序
attach 10237
:调试PID为10237的程序。b demo2.c:10
在demo2.c
的第10行打一个断点,同时左边终端到Hello --58
就停住了,没有再输出信息。- 执行一步,也就是执行
sleep(3)
,提示我们下一次要执行的是:
9 for(int i=0;i<10000;i++)\{
也就是第9行的for循环体。
- 查看
i
的值
- 再执行一步
- 这里用
s
再执行下一步,s
是会进入函数的,s
就是step
的缩写
果然进入了第5行的函数体中。
- 我们使用
c
命令,也就是continue:
继续执行代码,因为我们设置过断点,所以会来到调用函数的地方。
- 这里我们用
n
,来看看是否会进入函数。
发现是没有的,程序直接执行完了当前行,并且下一行要执行sleep(3)
。
也打印出了结果。当然,Hello --59
是上一次打印的。
- 我们还可以通过
kill
命令结束程序。
kill
命令不是gdb中的,所以我们要先通过q
或quit
退出gdb的shell,调试会话还没结束,它会问你一下要不要退出,我们输入y
。
我们一结束调试,旁边的终端就又开始输出信息了。等着,马上kill掉它😡。
进程被kill掉,程序就结束啦。
更多推荐
所有评论(0)