Linux:开发工具

Linux开发工具

软件包管理器

Linux中安装软件有三种方式:源码安装,软件包安装(rpm),包管理器yum(centos)、apt/apt-get(ubuntu)。

安装一个软件,不仅需要安装该软件本身,还需要安装它所依赖的其他软件或库等,例如安装python,还要安装它依赖的数学库、网络库等。使用源码安装或软件包安装,容易漏装软件依赖的其他软件或库,造成依赖缺失 ,同时软件和其所依赖的软件或库也会有版本兼容性问题。

包管理器会自动解决包的依赖问题。安装软件先要网络下载,再安装,即拷贝。这里必须使用root权限,当安装到系统里时,只要安装一次,任何人都能使用。

包管理器类似手机的应用商店。yum是Linux下非常常用的⼀种包管理器. 主要应用在Fedora,RedHat, Centos等发行版上。Ubuntu主要使用apt作为其包管理器。apt同样提供了自动解决依赖关系、下载和安装软件包的功能。

评估一个操作系统的好坏,主要看它的生态,生态包括社区、文档、人群、问题等,好的操作系统生态完善,比如出现故障可以通过文档、社区快速解决。

我们的Linux机器在下载软件时可通过内置链接下载,由于这些生态是国外的,社区中的中国开发者会把生态镜像,我们的Linux机器会更改下载链接(切换镜像源)。

如何确认自己已经连网?ping -c3 www.baidu.com ,如果没有报错则已经连网。

yum list 查找支持下载的软件,结合指令grep,如 yum list | grep sl ,只显示带sl的软件。由于我的机器是x86_64的,所以显示的软件不会是x86_32。第一列是软件名和其体系结构,第二列是版本号,第三列是软件提供平台。

yum install -y sl 安装sl,yum remove -y sl 删除sl。-y 为强制。

/etc/yum.repos.d 路径下的文件为yum源配置文件。

vim CentOS-Base.repo 可查看下载链接。

编辑器vim

简单介绍

vim --version 查看vim的版本。vim 打开vim。shift + ; 然后再按q即可退出,或者打开大写锁按两次Z(shift+连按两次z)。

在vim中写代码,先创建文件code.c,vim code.c 打开code.c,在该文件写代码。

写完代码后,按 Esc ,再 shift + ; ,输入 wq 退出,w是写的意思,即保存。

cat code.c 查看我们写的代码,gcc code.c 默认编译,./a.out 执行程序。

vim操作

vim有多种模式,常见的三种模式有命令模式插入模式底行模式 。打开vim默认是命令模式,在vim中输入文本需要插入模式,按 i 从命令模式切换到插入模式,如果需要显示行号,则输入 set nu 。输入完文本后如果想退出vim,则需按 Esc 回到命令模式,再 shift + ; 切换到底行模式,输入 q! 强制退出且不保存,输入 wq 保存并退出,只输入 w 则只保存。

命令模式方便快速编辑文本。

vim支持键盘上下左右移动光标,但更推荐 h 左移光标,j 下移光标, k 上移光标, l 右移光标。n + h 左移n次光标,其他同理。

gg 光标回到第一行,shift + gG 光标到最后一行。n + shift + gn + G 光标跳到第n行。

shift + 4$ 光标移到一行的末尾, shift + 6^ 光标移到一行开头。

w 以单词为单位往右移动光标,b 以单词为单位往左移动光标。同样的,n + w 光标往右移动n个单词。

yy 复制 当前行,p 在光标所在位置粘贴n + yy 复制n行,n + p 粘贴n次。

u 撤销 上一次操作,相当于windows的crtl+z。Ctrl + r 撤销u操作。一旦退出文件编辑,就无法撤销了,如果只是保存但没有退出,则还能撤销。

dd 剪切当前行或删除n + dd 剪切n行。

x 删除 光标位置所在的字符n+x 删除从光标开始往右n个字符。shift + xX 删除光标左侧内容,光标及其右侧内容不动,同样有 n + shift + x

yyddxX ,这些命令在复制或删除内容后都可以用 p 进行粘贴。

r + 字符 把光标所在位置的字符替换为指定字符。n + r 替换n个字符。shift + rR 批量式替换,即切换为替换模式,像插入模式一样输入内容,但会把原来内容覆盖。

shift + ~ 将光标所在位置的字母切换大小写 ,按住 shift 再长按 ~ 即可把整行的字母大小写替换。

Ctrl + v 从命令模式切换到视图模式 。例如切换到视图模式后,hjkl 移动光标进行区域选择,如按 j 选择某些行,再 shift + i 切换到插入模式,输入 // ,切换回命令模式即可批量注释指定行。

还可以配合 shift + g 使用,从命令模式切换到视图模式,shift + g 选中所有行,切换到插入模式输入 // ,再切换回命令模式,完成所有行的注释。同样,也可以配合 n + h/j/k/l 进行区域选择。

当代码全部被注释时,Ctrl + v 切换到视图模式,选择好区域,按 d 删除注释。

视图模式还有其他应用场景,例如给下面代码批量增加 \n

shift + 3# 选中光标所在位置的单词,查找并高亮显示。按 n 往上查找。

i 从命令模式切换到插入模式,a 在此基础上光标后移一格,o 则是会另起一行。

shift + ; 切换底行,! 代表强制,w 代表保存,q 代表退出,三者可以组合。wqshift + zz 保存并退出。set nu 显示行号,set nonu 取消行号。

进入底行模式,! + Linux命令 可以在vim中联动Linux的命令。

这样我们就可以在不退出vim的情况下使用Linux命令。vim 文件名 如果当前目录下没有该文件则创建该文件。我们用vim创建code.c

写入代码并保存,在底行输入 !gcc code.c 进行编译,再输入 !ls - l 可以看到编译出了可执行文件 a.out ,在底行输入 !./a.out 即可运行程序。

在底行输入 %s/src/dst ,如 %s/World/Linux 会把代码中的World替换为Linux。

在底行输入 vs test.c ,创建新文件test.c,并分屏

光标在哪个文件,底行操作的就是哪个文件。如上图底行操作的就是test.c,输入 wq 保存并退出test.c。如果想让光标移到code.c,在命令模式下按住Ctrl 再按 ww 即可。

底行也可以查找,在底行输入 /关键字 ,查找到关键字后高亮显示,按 n 会让光标移动到第一个关键字位置,再按就会到下一个关键字位置。

vim打开文件时,光标会停留在上次退出时的位置,vim + 文件 + n 用vim打开文件时光标自动跳转到第n行。

!v 自动匹配上一次v开头的命令,同理 !l 自动匹配上一次l开头的命令。

vim配置

cat /etc/redhat-release 查看系统版本。

用户家目录下有隐藏文件 .vimrc ,如果没有则自行创建。可以直接在 .vimrc 中输入配置信息,例如vim打开文件是不显示行号的,用vim打开 .vimrc ,在 .vimrc 中输入配置信息 set nu ,再用vim打开文件就会显示行号了。

vim是安装在系统中的软件,在默认情况下,vim会自动去用户家目录搜索 .vimrc ,如果没有该文件,则vim是默认行为,如果有则会根据文件的配置信息配置。在该文件中用 " 注释配置信息。

对于Centos7系统,在gitee中搜索vimforcpp,可一键配置vim。

配置完成后用vim打开文件。

写入代码后发现代码缩进是2格,如果想改成4格缩进,用vim打开.vimrc,把下图中的2改成4即可。

编译器gcc/g++

gcc只能编译C语言,而g++能编译C/C++,但二者选项完全相同。

gcc 文件.c 进行编译,默认形成 a.out 可执行程序,再用gcc编译其他 .c 文件时,形成的可执行文件会覆盖a.out。

预处理

gcc code.c -o mycode 把code.c编译成可执行程序mycode,gcc -o mycode code1.c code2.c ... 可以把多个文件编译成可执行程序mycode。

预处理功能主要包括进行宏替换,展开文件包含,进行条件编译,去注释等。

往code.c中写入如下代码。

gcc -E code.c -o code.i-E 该选项的作用是让 gcc 在预处理结束后停止编译过程,这个命令可以把code.c预处理后的结果保存到code.i中,让我们看到编译的中间过程。

可以看到,我们只有22行代码,预处理后竟有858行代码,这是因为展开了头文件。同时,code.i当中注释也被去掉了,M被替换为了100,由于定义了N,条件编译后只留下了Hello N。

code.i还是C语言,但仍需进一步编译,gcc code.i -o xxx 可以直接编译code.i。

上述代码中条件编译的含义是如果定义了N,则打印Hello N,否则打印Hello no N。条件编译的本质是裁剪了代码。

在test.c的代码中,#ifndef M表示如果没有定义M,则执行下面语句,否则执行else下面语句。预处理的去注释、宏替换等本质是修改编辑我们的文本代码。用gcc进行编译时,-D 能进行命令行级别的宏替换,把test.c中#define M 10注释掉,再用 gcc test.c -o xxx -DM ,在不指定具体数值时,相当于把#define M 1插入到代码中,gcc test.c -o xxx -DM=100 则是插入#define M 100,把-DM换成-DN 则插入#define N 1。

条件编译的用途:

  1. 软件根据专业度、收费情况区分业务,使用条件编译可以动态裁剪代码。比如某软件的社区版其实是专业版阉割一些功能后的,这时使用条件编译就不必为这两个版本写两份代码了。
  2. 内核源代码也采用条件编译进行代码裁剪。比如某些使用Linux的设备不需要上网,就可以把代码中的网络部分裁剪掉。
  3. 开放工具、应用软件也会用到条件编译。比如某些软件能在windows、Linux下使用,这其实是写了两份代码,如在windows下时就用条件编译把Linux的代码裁剪掉。

编译

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

gcc -S code.i -o code.s 把code.i生成的汇编代码保存到code.s中,-S 让文件只进行编译而不进行汇编,生成成汇编代码。

汇编

汇编阶段是把编译阶段生成的 .s 文件转成目标文件。

gcc -c code.s -o code.o 把code.s转成目标文件code.o,-c 让文件在汇编完成后停止编译。.o文件全称为可重定位目标文件,在win、vs2022下为xxx.obj文件。此时.o文件已经是二进制文件了,但不可执行,因为我们的源文件中会包含很多库方法,链接后才能生成可执行程序。

链接

生成可执行文件或库文件。通常用 gcc -c code1.c 生成同名.o文件,再 gcc code1.o code2.o ... -o code 生成可执行文件 code。

ldd 查看可执行程序依赖哪些库。

我们的C程序中,并没有定义printf的函数实现,且在预处理中包含的stdio.h中也只有该函数的声明,而没有定义函数的实现。那么,是在哪里实现printf函数的呢?系统把这些函数实现都放到名为 libc.so.6 的C标准库文件中去了,无论是我们自己写的程序还是Linux命令都要用到C标准库。在没有特别指定时,gcc 会到系统默认的搜索路径/usr/lib下进行查找,即链接到 libc.so.6 库函数中去,这样就能实现函数printf,而这也就是链接的作用。

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。Linux中后缀名一般为.a,Windows中后缀为.lib。

动态库 与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。在Linux中动态库⼀般后缀名为.so,Windows中为.dll,前面所述的 libc.so.6 就是动态库gcc 在编译时默认使用动态库

库的命名方式是前缀lib,再加上后缀.a或.so,如我们开发了一款名为xyz的库,它的正式名称为libxyz.a或libxyz.so

在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,会存在多种依赖关系。如⼀个源文件可能要调用另⼀个源文件中定义的函数。但是每个源文件都是独立编译的,即每个.c文件会形成⼀个.o文件。为了满足这种依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成⼀个可以执行的程序。这个链接的过程就是静态链接

比如一个源文件调用了printf函数,静态链接时就会到静态库中找到printf函数的实现并拷贝过来,如果多个源文件调用了printf函数就会拷贝多份,最后生成的可执行文件就会比较大,但在运行时不依赖静态库。

动态链接则是在编译时记录对调用函数的符号依赖,运行时到动态库进行库函数调用,拷贝少最后生成的可执行文件小。

动静态库对比:

  1. 动态库形成的可执行程序体积小,静态库形成的可执行程序体积较大。
  2. 可执行程序对静态库依赖小。动态库被多个程序共享不能缺失。
  3. 程序运行时需要加载到内存,静态链接会在内存中出现大量重复代码,动态链接相比节省内存和磁盘资源。
  4. 静态库更新,静态链接就要重新编译,动态库更新而动态链接不必重新编译。

创建文件code.c,写入代码,gcc编译后生成可执行文件code,ldd code 看到code依赖C标准库即libc.sofile code 可以看到更详细的信息。

gcc编译时默认使用动态库,如果想使用静态库则 gcc code.c -o code_static -static ,在此之前需要安装静态库 yum install -y glibc-static

静态库一般和动态库一样,安装在 /usr/lib64

同样一份代码,使用静态库后体积大了100倍。

使用命令 ldd 会提示不是动态可执行的。file code_static 显示为静态链接。

接下来演示C++。

安装C++静态库 yum install -y libstdc++-static

make/makefile

make命令makefile (Makefile)是一个文件,两个搭配使用,完成项目自动化构建。

会不会写makefile,从侧面说明一个人是否具备完成大型工程的能力。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。makefile带来的好处就是------"自动化编译",一旦写好,只需要一个make命令,整个工程完全自动编译,极大提高了软件开发的效率。

make是解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

创建文件myproc.c,写入如下代码。

创建文件Makefile,用vim写入如下内容。

第一行为依赖关系 ,冒号左边为目标文件 ,右边为依赖文件列表 ,可以有多个文件。第二行为依赖方法 ,必须以 Tab 开头。接下来输入 make 命令即可自动编译。

往Makefile中输入如下内容,完成项目清理。

输入 make clean ,可执行文件myproc就被清理了。

为什么编译myproc.c直接输入 make,而清理文件则是 make clean ?make命令扫描Makefile时从上向下扫描,默认形成第一个目标文件,即只输入 make ,只执行第一组依赖关系和依赖方法,如果想执行其他操作,需要带上具体的如 make clean 。在Makefile中调换这两组依赖关系和依赖方法的顺序,则输入 make 清理项目,输入 make myproc 编译myproc.c。一般情况下我们把要形成可执行文件放在前面。

像clean这种没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行。不过可以显式用make执行,即命令 make clean,以此来清除所有的目标文件,以便重编译。

一般把这种clean的目标文件设置为伪目标 ,用 .PHONY 修饰,伪目标的特性是总是被执行

myproc没有被.PHONY修饰,此时执行 make 命令会有如下提示。

用.PHONY修饰后,每次输入 make 都能进行编译,即总是被执行。

生成可执行文件操作一般不用.PHONY修饰,因为源文件被编译过且最近没有修改,就不必再编译。如果有许多源文件都被编译过了,后面只修改了个别源文件,重新编译时只需编译修改过的源文件即可,减少了编译时间。

stat 文件名 查看文件状态。

文件 = 内容 + 属性,文件记录了三种时间,Modify内容改变,时间更新;Change属性改变,时间更新,通常修改文件内容后Modify和Change都会改变;Access文件最近一次被访问的时间,由于文件经常被访问会产生大量IO操作,所以Access不会实时变化。所以,命令make 通过比较Modify时间来判断文件是否被修改过从而只编译被修改过的源文件。touch 后跟文件能把文件的这三种时间同时改变。

所以,.PHONYmake 忽略源文件和可执行目标文件的Modify时间对比

make是如何工作的?参照如下代码,#为makefile的注释符号。

在默认情况下,只输入make命令:

  1. make会在当前目录下找名字叫Makefile或makefile的文件。
  2. 如果找到,它会找文件中的第一个目标文件,即在上面的代码中,它会找到 myproc 这个文件,并把这个文件作为最终的目标文件。
  3. 如果 myproc 文件不存在 ,或是 myproc 所依赖的 myproc.o 文件的文件修改时间要比 myproc 这个文件 ,则执行后面所定义的命令来生成 myproc 这个文件,即执行 gcc myproc.o -o myproc
  4. 如果 myproc 所依赖的 myproc.o 文件不存在,那么 make 会在当前文件中找目标为 myproc.o 文件的依赖关系,如果找到则再根据它的依赖方法生成 myproc.o 文件。如果没有找到,则找 myproc.o 的依赖方法......以此类推,最终到 myproc.c 。这里类似一个堆栈的过程。
  5. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,如最后被依赖的文件找不到,那么make就会直接退出并报错。

下面介绍语法。

BIN=myproc 可以把BIN理解为变量或者宏,.PHONY:test 与前面的clean类似,echo $(BIN) 使用make命令时会打印出myproc。

如果不想回显命令 echo myproc 则在命令前带上 @

每一组依赖关系和依赖方法就可以按如下的方式写。

@^ 分别代表目标文件和依赖文件列表,在依赖方法中可以用 $@ 代替 $(BIN)$^ 代替 $(SRC)

使用make命令时不想依赖方法回显,同时想显示编译信息,可以按如下操作。

%.o 展开同名.o,%.c 展开当前目录下所有.c,$< 对展开的.c文件一个一个交给gcc。编译的习惯是把所有.c编译成.o后再链接。

SRC=$(shell ls *.c) 使用shell命令行方式,获取当前目录所有.c文件,SRC=$(wildcard *.c) 使用wildcard函数有同样效果。OBJ=$(SRC:.c=.o) 将SRC中的.c文件替换为.o文件。

进度条

倒计时程序

\r 表示回车,即光标回到行首,\n 表示换行,编程语言中常把 \n 直接解析为 \r\n 。用printf打印字符串时,字符串会先在缓冲区中,程序退出后刷新缓冲区,字符串才会显示在屏幕上。printf("Hello World\n") 由于打印的同时换行,\n 导致了行刷新,所以字符串会在程序退出前显示在屏幕上。

运行上图代码,发现程序是先休眠3秒,再显示出字符串,程序本该是顺序执行的,但此处似乎是先执行sleep。这就是因为打印字符串时没有\n,没有刷新缓冲区,字符串停留在缓冲区中直到程序退出才显示到屏幕。在printf后调用函数fflush能立刻刷新缓冲区。另外要注意的是,用 man 查看手册时,man sleep 查找的是Linux中的sleep,man 3 sleep 查找的才是C语言的sleep函数。

下面是用C语言实现10秒倒计时。

进度条程序

进度条首先要一个滚动的条带,再要一个百分比显示进度,当进度条未满而条带和百分比不变时,为表明程序仍在进行,还需要一个旋转光标表示正在加载。

创建 main.c 文件,在此文件中调用进度条函数,创建 process.h ,声明进度条函数,创建 process.c 实现进度条函数。创建 Makefile 实现自动化编译。

以上是进度条的基本原理,对于具体情境,如下载或上传文件,total为总下载量,current为已下载量,需要让进度条函数根据这两个传入的参数生成进度条。

这里使用了函数指针,在main中调用DownLoad、UpLoad时传入进度条函数指针即可。使用进度条函数FlushProcess时,直接传入FlushProcess,如果想使用其他版本的FlushProcess1、FlushProcess2等,仅需往DownLoad、UpLoad传入函数指针参数即可,不用在函数内部修改进度条函数,做到了一定程度的解耦

git

版本控制器,是能让你了解到一个文件的历史、发展过程的系统。即是一个可以记录工程的每一次改动和版本迭代的一个管理系统,同时也方便多人协同作业。

目前最主流的版本控制器就是 git 。git 可以控制电脑上所有格式的文件。对于开发人员来说,git 最重要的就是可以帮助管理软件开发项目中的源代码文件!

在gitee中创建远程仓库Linux_test。

创建成功后如图所示。点击克隆/下载,获取远程仓库的链接。

git clone 远程仓库链接 在Linux中用命令把远程仓库拉取到本地。git --version 可查看是否安装git,如果安装了则会显示git的版本信息,如果没有安装则输入命令 yum install gitapt install -y git

进入 linux_test ,即可看到与gitee中一样的内容。

进入 linux_test ,其中隐藏目录 .git 为隐藏的本地仓库。

git提交时,只会提交变化的部分。比如修改某源文件的代码,git只会记录增加删除等修改信息,不会保存之前的版本,如果需要之前的版本,git可以根据修改信息倒推,从而恢复之前的代码。

在Linux上用命令把代码提交到git远程仓库 。首先要输入命令 git add 文件 ,此时文件会先存放在 .git 的暂存区,git status 可以查看当前状态。

接下来提交到本地git仓库 git commit -m "日志信息" ,其中日志信息一般为"新增了源文件"、"修改了什么bug"等,git log 可以查看日志信息。

首次使用git需要输入用户名和邮箱,使用gitee中的即可。

最后同步git本地仓库和远程仓库 git push

如果本地仓库被删掉了,再执行命令 git clone 远程仓库链接 即可在本地同步,恢复文件。

git进行文件的版本管理,只能管理源文件,即 .c 、.cpp 、.h 等,.o 、.s 等临时文件不应该用git管理。.git 中的文件 .gitignore 可以帮助本地文件后缀过滤,即如果文件的后缀与 .gitignore 中的配置信息一致,则不会被提交。

所以,.gitignore 中保存的是需要忽略的特定文件后缀,当然,也可以增加或删除要忽略的文件后缀。

对于同一个仓库,如果程序员A先修改了其中源文件并提交,程序员B想再提交就会发生冲突,因为远程仓库和程序员B的本地仓库不一致了,需要先用命令 git pull 同步远程仓库和本地仓库,才能正常用 git push 提交。

调试器gdb/cgdb

程序员开发期间所处的环境为debug,后续测试工程师测试release模式,通过后上线release模式。

在Linux中gcc/g++编译的可执行程序为release模式,不能调试。

debug模式下才能对可执行程序进行调试,在编译时加上选项 -g 让最后形成的可执行程序添加调试信息,使之成为debug模式。

或者 gcc XXX.c -o XXX -g

对比release模式,debug模式可执行文件体积增大。

创建新目录 GDB ,在该目录下创建 mycode.c ,写入如下代码。

gcc mycode.c -o mycode -g -std=c99 编译代码。然后使用gdb调试代码 gdb mycode

rrun 运行程序,llist 查看代码。

按回车向下翻看代码。

l n 从第n行开始查看。 l 函数名 跳转到想要查看的函数。如果可执行文件链接了多个.c文件,l XXX.c:n 从第n行查看其他.c文件。

b 行号 在指定行号打断点,r 运行,运行到19行停止,c 继续运行至程序结束。qquit 退出gdb。

显然gdb调试是不方便的,代码、调试信息都混在一起。cgdb 是更方便的调试器,下载 yum install -y cgdb 。cgdb命令与gdb命令一致。

上方界面不好控制,仍需要 l 命令在下方查看代码。打开cgdb后,Esc 进入代码屏,按上下键滚动查看代码;i 回到gdb屏。

打断点的方式:b xxx.c:行号b xxx.c:函数名b 行号 。可以看到15、16、17行的行号变红,说明打上断点了。

info b 查看断点信息,Num为断点编号。

d 断点编号 删除断点。

gdb不退出,断点编号依次递增。

退出重新使用调试器,在18行打断点,r 运行到18行停止。nextn 逐过程,相当于vs2022中的F10。

此时输入 r 会问你是否从18行断点处重新开始,输入y重新开始。

sstep 逐语句 ,相当于vs2022的F11。gdb会自动记录最近的一条命令 ,此时按回车会执行 s 命令。输入 r 重新回到断点处。

bt 查看调用的栈帧。

在Sum函数中,如果想直接得到函数返回值,使用 finish 命令。

p 变量名 查看变量或表达式的值。

打断点时,想禁用某些断点但不想删除断点,info b 可以看到表格中的Enb,表示使能,关闭使能则禁用断点 disable 断点编号 ,打开使能 enable 断点编号

cgdb也支持按上下键查找历史命令。当忘记命令具体是什么时,输入部分字母再Tab,可显示出相关命令。

c 执行到下一个断点前或执行完程序。

断点的作用是把代码进行 级别划分,以块为单位快速定位,从而方便找到代码出错的地方。until 行号 执行到指定行号,cfinishuntil 配合使用帮助快速定位。

display 变量 查看变量时能常显示。

undisplay 编号 关闭变量的常显示。变量出了作用域后也能自动关闭常显示。

info locals 能显示函数内所有被定义的变量。

watch 执行时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运行期间的值发生变化 ,gdb会暂停 程序的执行,并通知使用者 。不用时像删除断点一样使用 d 编号 命令。

set var 变量=值 在调试时修改变量。

b 行号 if 变量 == 值 添加条件断点d 断点编号 删除条件断点。

condition 断点编号 变量 == 值 给已有断点追加新条件。