今天我们利用一个两层函数调用的简单程序——输入两个整数求最大公约数。来学习与理解gdb调试的过程。
首先进行代码编写
main函数:
1 | #include<stdio.h> |
cal()函数比较两个输入数值大小,并将大的数字放在前面,作为下一个函数的参数:
1 | #include"res.h" |
res()函数利用辗转相除法求最大公约数:
1 | int res(int a, int b) |
还有两个函数声明的头文件cal.h
和res.h
:
cal.h
1 | int cal(int a, int b); |
res.h
1 | int res(int a, int b); |
编写Makefile文件,注意需要每一条语句都加上 -g
属性,否则可能会出现有些地方无法调试,比如函数无法单步进入。
编译链接文件
1 | make |
进入main.out程序调试语句
1 | gdb main.out |
开始运行函数
1 | start |
逐条语句执行
1 | n |
单步进入函数内
1 | s |
查看当前函数调用栈,可以看到这里栈内有两个函数,栈顶是当前进入的cal函数,用于比较两个输入数据的大小并调整顺序。栈底是main函数。
1 | bt |
继续执行代码,在执行完判断并交换的逻辑之后,我们可以看到输入时a=33,b=66。现在值已经交换过来了。p
命令用于打印某个变量的值。
这时可以看到又到了一个函数res这一行,我们再次单步进入,并查看函数栈
可以看到栈内已经保存了三个函数了。但此时由于参数还没有传进来,所以res的两个参数还是一个系统随机的初始值,我们继续执行一条语句就可以看到参数已经传进来了。
当我们打印出变量m,c的地址时,由于整形占的是四个字节,可以看到整形变量的地址是连续分配的。
我们还可以在循环中打印c的值,实时查看辗转相除求最大公约数的过程。
明白整个过程后,q退出调试。