Linux:git和gdb/cgdb
一:在XShell上使用git
步骤1:安装git命令行
sudo yum install git
步骤2:注册git账户和仓库,并点击克隆/下载,把HTTPS复制
步骤3: 在显示屏上输入下面命令,然后按提示输入自己的用户名和邮箱
git clone https://gitee.com/ctdhjnds/linux-code.git
所以我们就成功的在Linux克隆了自己的仓库,使用ll命令就可以查看我们的仓库
步骤4:输入下面命令
git add lesson4
add会将lesson4这个目录上传到当前git的工作区的暂存区,这是因为如果我们想要将多个文件多次推送到git的时候我们只需要多次add这些文件到暂存区,然后一次就可以推送到git了。
步骤5: 输入下面命令
git commit -m "新增文件"
commit会将暂存区中的文件目录推送到git仓库中,在演示中即将lesson4这个目录推送到仓库;其中“新增文件”表示的是提交日志信息 ,写是为了我们之后更好的了解我们提交的是什么
步骤6:输入下面命令
git push
然后按提示输入用户名和密码
git status:查看状态
git log:查看用户的所有提交信息
git提交的时候,只会提交变化的部分
二:gdb调式
Linux的工作模式有两种,一种是Debug模式,另一种是Release模式。在Linux下我们编译好的代码无法直接调式,这是因为gcc/g++默认的工作模式是Release模式。如果我们在gcc/g++命令后面加上-g选项,就可以让最后形成的可执行文件添加调试信息,使文件处于Debug模式。因此,程序要调试,必须是Debug模式,也就是说文件编译时必须加上-g选项。
2.1 使用gdb/cgdb调试代码
gbd/cgdb + 文件名进入gdb,quit退出,特别注意的是由于cgdb的使用比gdb好用,并且cgdb的,命令和gdb一样,所以我们gdb只做简单演示,而使用cgdb需要安装cgdb,命令如下:
sudo yum install -y cgdb
首先我们创建了一个mycode.c文件并使用gcc mycode.c -o mycode -std=c99命令生成目标文件mycode,接着我们gdb mycode命令就可以进入gdb了,但是我们输入l列出代码内容的时候发现居然报错了,这是因为我们的mycode文件处于Release模式,当我们将gcc mycode.c -o mycode -std=c99加上-g选项时(gcc mycode.c -o mycode -std=c99 -g),再输入l就可以列出代码内容了
mycode.c代码:
#include <stdio.h>
int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}
2.2 gdb/cgdb的命令
1. l(list):列出内容
l + 数字:列出行号附近的代码
如上图所示: l 1的意思是列出第一行附近的代码,由于l一次只能列出10行的内容,所以我想要看完整的代码可以按Enter键直至所有代码都展示出来
2. b(break):打断点
b + 数字:在数字行打断点
b + 文件名:数字:在文件名第数字行打断点
b + 文件名:函数名:在文件名函数入口打断点
当我们打完断点后我们可以看到文件对应行行号就会变红
3.info b:查看断点信息
第一列表示的是断点的编号
4. d :删除断点
d + 断点编号:删除编号的断点
如上图所示,分别有1,2,3三个断点编号的断点,当我们想要删除18行的断点时(即编号为2的断点) ,我们就可以直接使用命令的 d 2,然后我们在info查看断点信息,果然18行的断点就被删除了
注意:删除断点不能d + 行号,当cgdb没有退出的时候,断点的编号会依次递增
5. n(next) :
相当于VS的F10(逐过程),如果存在函数,不会进入函数而直接得到函数返回值
如上面两张图所示,原本程序停在了18行,当我们执行n命令时,程序就不会进入函数内部
6. s(step):
相当于VS的F11(逐语句),如果存在函数就会进入函数内部执行,并且cgdb会记录最新一条命令的内容,所以我们可以直接按Enter键执行最新一条命令
如上两张图所示,原本程序停止在18行,执行s命令后程序进入函数内部
7.r(run) :执行代码
当代码中有断点的时候,使用r就会将程序停止在断点处,否则就会直接跑完整个程序
如上图所示,在18行处有一个断点,执行r命令程序就停在了第一个断点处
8.p(printf):打印变量的值
p + 变量名:打印变量的值
由上图可知,p + 变量名只能看一次查一次
9.info locals:查看当前函数所有临时变量的值
如上图所示:当前程序正在执行Sum函数,执行info locals命令时,就将Sum函数内部的临时变量i和result的值打印出来了
10.finish:快速跳出当前函数并返回执行结果
如上两张图所示,程序原本在Sum函数内部,执行finish命令后,程序就执行完当前函数并返回执行结果
11.until:执行到指定行号
如上面两张图所示:此时程序执行到第6行,当我们想程序不要继续执行Sum函数直接跳转到第10行开始执行时,我们可以使用until 10命令,程序就自动执行完后序的Sum函数直接跳转到第10行
12.display:观察打印变量的值(长显示)
如上图所示,执行display i命令就会打印i的值,display result就会打印result的值,并且我们可以看到i和result的值一直显示在显示器上,并且每个变量名之前都有一个编号
13.undisplay:取消打印观察变量的值
当我们不想使用display观察打印变量的值时,使用undisplay + 对应变量的编号就可以了,如下图所示,当我们不想观察result的值的时候,由于result的编号为2,执行undisplay 2命令就取消对result的值的观察打印了
三:三个调式技巧
3.1 watch
watch + 变量相当于也是一个断点,当变量的值发生改变时,系统就会自动提示我们并打印出新旧变量的值,如上图所示,第一次执行s命令时watch没有任何提示,第一次执行s时由于result的值发生改变所以系统将result的新旧值打印出来。这个调试技巧非常好用,就比如在一个程序中,可以使用watch监视常变量,当由于常变量的非法修改导致程序错误时watch就会提示
3.2 set var:在调试过程中改变程序里变量的值
由上图可知,此时i的值为4 ,当我们在程序执行过程中如果我们想要改变变量i的值为5的时候我们就可以使用set var i = 5,因此变量i的值就变成5了。这个调试技巧可以应用于当一个程序中我们不确定是否是某个变量的值的错误导致结果的错误想要改变这个变量的值是否程序无误就可以使用set var
3.3 条件断点
设置条件断点:b + 行号 + if 变量 == 值
如上图所示:执行b 8 if i == 3我们给第8行设置了一个条件断点,当变量i 的值为3的时候断点才触发,我们执行info b查看断点可以看到这个条件断点添加了stop only if i == 3这条语句表明只有当i的值为3 的时候才会触发断点程序停止,如下图所示
condition 断点编号 变量 == 值:给已存在的断点新增触发条件