一般用gcc指令编译过的程序不能被用于gdb(一个Linux自带的调试工具)调试,要用gcc -g xxx.c指令才可以。
用gdb调试要保存.c的源代码,否则会有一些调试功能无法使用(比如调试时无法显示行号)。
gdb ./xxx.out:表示调试xxx文件
在调试模式下(括号中含有gdb),输入l(或者list)显示整个源代码,输入break打断点,输入start开始调试(此时会显示断点在哪里),p x表示输出x这个变量的值,n继续下一步执行,当断点打到调用的函数前可以用s指令来进入函数内部,bt查看函数堆栈(可以显示当前函数调用的堆栈情况), f n代表转到相应的标号n堆栈进行函数的调用。
本次练习案例中,change函数的a和b是形参,他们值的改变,不能代表main函数里的实参也改变了。
按q退出调试
函数的参数是形参,a、b为参数名,将a,b传递进函数的时候,传入的是两个数值,在函数里a、b相当于局部变量,无论怎么改变,有效范围只在该函数里面,对于main里面的a和b是没有影响的。即函数在传递数值的时候是默认把变量里的值传进去,故传入的值是实参,而a、b作为一个代号只代表一个变量的名称,而且该变量在函数里面就相当于一个局部变量,无法影响主函数。
传入时只是传入了a,b被赋的数值
gdb 是gcc自带的一种调试工具 ;
gdb -help查看gdb用法;
gcc -g +源代码文件-o +执行文件名(.out 类型) 生成可调试的执行文件;
gdb +./ 可调试执行文件名;
进入gdb调试后,l表示查看程序;回车表示继续上一命令;start表示调试,会自动在main函数第一行程序加断点;n表示执行新行;s(step)表示进入函数中,需执行到函数所在行;p+变量名表示打印变量数值,bt 查看堆栈;f 1:切换到堆栈中编号为1的函数中;q:退出调试;
change(int a,int b);实际过程中,只是传递给了a,b数值,作用范围仅在函数内部,故不起换值作用,而change(int *a,int *b )传递给了参数地址,对存储单元中的值进行替换,起实际作用。
gdb工具的使用
gcc -g main.c -o main.out
#include<stdio.h>
void change(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=5,b=3;
change(&a,&b);
printf("%d %d",a,b);
return 0;
}
初识指针,调用函数交换a和b的值
使用调试功能 gcc -g
gdb ---> 断点调试,单点调试
gcc -g 文件名.c -o 文件名.out ---> 使用gdb编译
gbd ./文件名 ---> 开始执行db调试
l:(list)列出源码
回车继续执行刚刚的命令
start ---> 开始执行
break n ---> 截取第n行断点
print或p a ---> 打印输出变量a
n ---> 跳到下一行继续执行
s ---> step 跳入函数
bt ---> 查看函数堆栈
f ---> 切换函数堆
f 1 ---> 跳转到函数1
q ---> 退出调试
gdb 断点调试,单点调试
gcc -g 文件名.out -o 文件名 .out 使用gdb编译
gbd ./文件名.out 执行
(gdb) l 或list 显示源代码
l:(list)列出源码
回车继续执行刚刚的命令
start开始执行
break n ---> 截取第n行断点
print或p a 打印输出a
n 跳到下一行
s 进入函数
bt 查看函数堆栈
f 切换
f 1 跳转到函数1
q 退出调试
gdb 断点调试,单点调试
gcc -g main.out -o -g使用gdb编译
gbd ./main.out 执行
(gdb) l 或list 显示源代码
回车继续执行刚刚的命令
start开始执行
print或p a 打印输出a
n 跳到下一行
s 进入函数
bt 查看函数堆栈
f 1 跳转到函数1
q 退出调试
使用调试功能 gcc -g
gdb ./ //开始进行gdb调试
list //列出程序
start //单步开始
p //打印变量值
n //继续执行
s //step 跳入函数
bt //查看函数堆
f //切换函数堆
GDB工具
s:执行一行代码(若有函数调用进入该函数)【Step Into】
n: 执行一行代码(函数调用一并执行)【Step Over】
p<变量名>:显示变量的值
q:退出
l:(list)列出源码
gdb 终端调试工具
gcc -g main.c -o main.out 生成可调式的执行文件
注意,此时源代码.c文件仍不可删除。否则仍然不支持调试。
调制过程:
1、 gdb main2.c 进入调试模式;
2、调试模式 输入 “list” 或者 “l” 列出当前项目的软件源代码;
3、“start” 开始调试,默认断点在main函数的第一行代码;
4、"p" 表示print , 输出变量值;
5、“n" 表示执行一行代码挑到下一行;
6、 “s” 表示按步骤执行代码, 可进入调用函数内部;
7、“bt” 表示显示函数堆栈, 可显示有哪些函数在运行;此时使用"p"打印的是当前函数中的变量值, 即标号为#0的函数;
8、"f" 切换当前跟踪的堆栈内函数; eg: f 1(1 为“bt”中的函数编号);
9、“q”跳出调试模式;
变量前加*表示指针,接收函数时变量前加取地址符&。
中间有空格末尾无空格if(i!=n)printf(" ");
gdb调试:
gcc -g main.c -o main.out 编程可以单步调试的程序;
l 查看代码;
start 从main函数开始执行;
n 下一行
p 打印
s 进入调用函数
bt 查看函数堆栈
f 栈堆内切换
q 退出调试
gdb调试:
1、gcc -g main.c -o main.out 编程可以单步调试的程序;
2、l 查看代码;
3、start 从main函数开始执行;
4、n 下一行
5、p 打印
6、s 单步,进入函数等
7、bt 查看堆栈信息
8、f * 切换堆栈