【Linux】linux基础开发工具(三) 版本控制器Git、调试器 - gdb/cgdb使用、一些实用的调试技巧
文章目录
- 一、版本控制器Git
- 背景
- 版本控制器
- git的特性
- git使用
- .gitignore
- 一个细节
- 二、调试器 - gdb/cgdb使用
- debug/release
- 使用gdb/cgdb
- 打断点/取消断点(F9)、运行到断点(F5)
- 逐过程、逐语句
- 监视
- 启用/禁用断点
- 小tip
- 调试常用技巧
- watch
- set var
- 条件断点
一、版本控制器Git
背景
不知道你⼯作或学习时,有没有遇到这样的情况:我们在编写各种⽂档时,为了防⽌⽂档丢失,更改失误,失误后能恢复到原来的版本,不得不复制出⼀个副本,⽐如:
“报告-v1”
“报告-v2”
“报告-v3”
“报告-确定版”
“报告-最终版”
“报告-究极进化版” …
每个版本有各⾃的内容,但最终会只有⼀份报告需要被我们使⽤ 。
但在此之前的⼯作都需要这些不同版本的报告,于是每次都是复制粘贴副本,产出的⽂件就越来越多,⽂件多不是问题,问题是:随着版本数量的不断增多,你还记得这些版本各⾃都是修改了什么吗?
⽂档如此,我们写的项⽬代码,也是存在这个问题的!
版本控制器
为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统,同时也⽅便多⼈协同作业。
⽬前最主流的版本控制器就是 Git 。Git 可以控制电脑上所有格式的⽂件,例如
doc、excel、dwg、dgn、rvt等等。对于我们开发⼈员来说,Git 最重要的就是可以帮助我们管理软件开发项⽬中的源代码⽂件。
git的特性
在多人开发时,如果一个人要push自己本地仓库里的代码到远端仓库前,如果本地仓库和远端仓库里的内容不一致,也就是远端仓库的内容被其他人修改过了,推送方就会无法推送,需要先将推送方的本地仓库和远端仓库同步。通过这种限制提交的方式,可以保证远端仓库一直都是最新的,并且是增量提交。
1、仓库本质就是目录。
2、前面介绍git可以同步仓库说明git本身除了版本控制,也提供网络功能。
3、本地仓库和远端仓库,本地git服务和远端git服务没有本质区别。
4、git是一种去中心化的版本控制策略,每个人都只使用自己的本地仓库也可以,远程仓库的作用是方便多人同时开发。
git使用
将远端gitee仓库拷贝到本地:(git clone 后面跟待同步远端仓库的URL)
当远端仓库被修改后,同步本地仓库和远端仓库:
克隆下来的以远端仓库名命名的目录叫做当前工作区,这个目录下有一个隐藏文件叫做.git,它是本地仓库。
所以以后我们编写的代码想要被git管理起来,首先要把代码拷贝到本地目录(当前工作区)下,然后再把代码托管给本地仓库。
原理懂了,那具体该怎么操作呢?下面以提交一个新建文件test.c到本地仓库并将本地仓库与与远端仓库同步为例:
1、首先保证test.c 已经在本地目录下,在本地目录里输入以下指令,代表把当前本地目录下新增的内容添加到本地仓库中。
2、上面的操作其实并没有真的把代码合并到了本地仓库中,而是存到了本地仓库里的一个叫index的文件里,这个文件一般被叫做暂存区,它的作用是如果你添加代码后悔了,可以将暂存区的代码直接丢弃,后续可以重新添加,不影响本地仓库。
确认提交没问题后要把暂存区的内容合并到本地仓库的指令如下:
-m 是 “message”(提交说明、提交信息)的缩写,-m 后面的信息叫做提交日志,内容一般是本次提交调整了什么东西。
3、最后一步是将本地仓库和远端仓库同步:
这里一般还会让你输入账号密码,就是登陆gitee时的账号密码。
.gitignore
.gitignore是本地目录下的一个隐藏文件,它的作用是在提交文件到本地仓库乃至远端仓库时过滤掉特定后缀的文件,因为git主要对源文件、头文件、文档等进行托管,所以我们不希望一些其他文件污染我们的git仓库。.gitignore文件里的内容就是提交时会忽略的文件后缀,里面已经有许多系统自动配置的后缀了,如果我们想让它会忽略特定的文件后缀,可以手动在.gitignore里做配置。
一个细节
仓库本质记录的是文件的变化
仓库不会把每一个版本的代码都存一份,因为这太占据空间了,空间太大了网络传输速率也会变低,所以仓库只会记录的是文件的变化过程,比如在哪里插入什么代码,多少行到多少行删除了代码,除此之外还会记录仓库里文件的创建和删除记录,以后想回退版本逆着变化过程执行就行了。
git log指令可以看到仓库历史的修改过程。
二、调试器 - gdb/cgdb使用
下载gdb/cgdb:
yum install -y gdb
yum install -y cgdb
debug/release
下载完后就可以用 “gdb 可执行程序” 指令来调试代码了,quit指令是退出gdb,可是一开始是无法调试的:
原因是gcc编译程序默认是release模式发布的,我们知道release版本是不包含调试信息的,只有debug版本才会添加调试信息。
那要如何证明gcc默认编译出的可执行程序确实是以release发布的呢?下面readelf指令会读取可执行程序二进制文件的构成段是否包含debug信息,我们发现它确实是没有debug信息的。
如果我们想让gcc默认编译出的程序以debug发布,需要加上-g选项:
使用gdb/cgdb
用gdb打开可执行程序时命令行默认是不会把我们的代码显示出来的,还需要用指令
l或者list+行号 查看代码,显然这比较麻烦,cgdb更方便,它可以将命令行和代码都同时显示出来:
接下就要开始介绍用cgdb调试代码的各种指令了:。
打断点/取消断点(F9)、运行到断点(F5)
b
(break point)
这是用来打断点的,最简单的方式就是在b后面跟行号,表示在某一行打断点。
info
(information)
这是用来查看断点信息的,示例如下:
打断点还可以 文件名:行号 或者 文件名:函数或者直接跟函数名,直接跟函数名是打在函数的开头处 (注意这里的文件名是源文件名)
还有一点,在一轮调试周期中,断点编号的线性递增的,断点被删除后编号还会被保留,新断点编号从它的下一个编号开始。
d
删除断点,删断点不能以行号来删,需要以断点编号来删,因为打断点方式太多了,所以用断点编号来删最直观。
也可以直接d删除所有断点:
r
(run)
当我们打好断点后,r就可以将程序运行到断点处。类似F5,但是它无法像F5那样跳转到下一个断点,想跳转断点需要借助后面介绍的continue。它只能在程序还没运行时使用,若运行后r就是重新运行程序。这里有三个细节:
1、gdb启动调试时,只是开启了gdb,程序并没有运行起来。
2、r表示在gdb场景中,运行我们的被调试的程序。
3、没有断点时,r会让程序直接运行结束。
逐过程、逐语句
n
(next)
逐过程执行,类似F10,前提是要先将程序运行起来。
s
(step)
逐语句执行,类似F11。
监视
p
显示一次变量的值,也支持查看表达式的值,如a+b。
display
将变量设置为常显示,想查看地址就加上&。
undisplay
取消变量常显示,这里和d一样,只能指定编号取消。
until
执行到指定行号,做代码的区域式执行。当程序已经跑起来时,我们如果一直s或者n都在一个循环里,确定循环没问题想跳出循环到特定位置,又不想打断点,就可以用until,但是区域执行代码还是接下来要介绍的continue更常用。
c
(continue)
从当前位置开始连续执行程序,直到运行结束或者运行到下一个断点处。它只有在程序执行了r指令后才能使用。
finish
把当前函数执行完然后停止。如果我们已经s进入到函数内部了,不想从头到尾s一遍函数,就可以用finish。
bt
(backtrace)
查看堆栈
info i
查看当前正在调试的程序信息。
info local
查看当前栈帧空间的局部变量,类似自动窗口。
启用/禁用断点
当我们不用一个断点时应该优先禁用它而不是删除它,这是为了保存调试信息。
disable
禁用断点
enable
启用断点
小tip
gdb会记录我们最近执行的命令,所以当我们需要多次执行一个命令时,可以第一次输入我们想要执行的命令,后面直接回车就会一直执行该条命令了。
调试常用技巧
watch
执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者。
watch也是一种断点,它也有断点编号,只不过它的对象是变量或者表达式,它的功能类似于display。
它的使用场景是如果你有⼀些变量不应该修改,但是你是怀疑它被修改导致了问题,你就可以watch它,如果它的值变化了,就会通知你。
set var
它可以在调试过程中更改指定变量的值,确定是否是这个变量造成的问题。
它还可以用它来更改循环次数或者将一个疑似野指针的指针改成nullptr。
条件断点
添加条件断点:
给已经存在的断点新增条件:
以上就是小编分享的全部内容了,如果觉得不错还请留下免费的赞和收藏 如果有建议欢迎通过评论区或私信留言,感谢您的大力支持。 一键三连好运连连哦~~