【Linux】Linux的基础工具

目录

[1. 整体学习思维导图](#1. 整体学习思维导图)

[2. 安装工具yum/apt](#2. 安装工具yum/apt)

[2.1 安装工具是什么?](#2.1 安装工具是什么?)

[2.2 理解安装的过程](#2.2 理解安装的过程)

[3. Vim 编辑器的使用](#3. Vim 编辑器的使用)

[3.1 vim的多模式](#3.1 vim的多模式)

[3.2 命令模式:快速编辑](#3.2 命令模式:快速编辑)

[3.3 替换模式](#3.3 替换模式)

[3.4 底行模式](#3.4 底行模式)

[3.5 视图模式](#3.5 视图模式)

[3.6 小技巧](#3.6 小技巧)

[4. gcc/g++](#4. gcc/g++)

[5. 理解编译和库的基础概念](#5. 理解编译和库的基础概念)

[5.1 理解条件编译](#5.1 理解条件编译)

[5.1.1 命令行宏定义](#5.1.1 命令行宏定义)

[5.1.2 条件编译的用途](#5.1.2 条件编译的用途)

[5.1.3 汇编的由来](#5.1.3 汇编的由来)

[5.2 动静态库](#5.2 动静态库)

[5.2.1 库的命名方式](#5.2.1 库的命名方式)

[5.2.2 动静态库的对比](#5.2.2 动静态库的对比)

[5.2.3 ldd/file/-static指令](#5.2.3 ldd/file/-static指令)

尝试链接

[6. make/makefile是什么?](#6. make/makefile是什么?)

[6.1 依赖关系,依赖方法](#6.1 依赖关系,依赖方法)

[6.2 推导](#6.2 推导)

[6.3 进度条](#6.3 进度条)

[6.3.1 先做一个倒计时程序](#6.3.1 先做一个倒计时程序)

[6.3.2 做一个进度条程序](#6.3.2 做一个进度条程序)

[6.4 makefile的使用拓展](#6.4 makefile的使用拓展)

[7. Git版本控制器](#7. Git版本控制器)

[7.1 git的安装](#7.1 git的安装)

[7.2 创建远端仓库](#7.2 创建远端仓库)

[7.3 git三板斧](#7.3 git三板斧)

[7.3.1 git add](#7.3.1 git add)

[7.3.2 git commit](#7.3.2 git commit)

[7.3.3 git push](#7.3.3 git push)

[7.4 补充知识](#7.4 补充知识)

[8. gdb调试器](#8. gdb调试器)

[8.1 debug模式](#8.1 debug模式)

[8.2 cgdb调试指令](#8.2 cgdb调试指令)


1. 整体学习思维导图

2. 安装工具yum/apt

2.1 安装工具是什么?

打个比方来说,我们的手机在下载一款我们需要的APP时,我们一般会去应用商店安装,而这个应用商店就可以称作为一个安装工具。

在Linux中的安装分为多种:

  • 第一种:源码安装,顾名思义就是给我们源码自己运行安装,这无疑是很难得,我们并不了解他人的程序,会让我们拿到该软件时还需花费一定时间去了解。

  • 第二种:软件包安装rpm,这个软件包不是指我们平时手机下载的安装包,手机的安装包是一个集合体,简单说一款软件是由多种程序所构成的,包含了很多的库调用,而这里的软件安装包只是软件并不包含库,这意味着我们在安装完这个安装包后依然会因为缺少一些库的支持而不能运行。

  • 第三种:包管理器 yum(Centos)/apt/apt-get(ubuntu),包管理器就如同一个应用商店,它将安装包和所需库都准备好了,我们使用它下载必定不会出现缺少库文件运行不起来的情况(我想软件开发者也不会让这种情况发生)。

2.2 理解安装的过程

以下是安装指令:

bash 复制代码
yum [选项] install(安装)/remove(移除) name(软件名称)
-y 安装时不询问是否同意

yum list 列出所有可以安装的程序包

通过以上选项我们又产生了新的问题:

  • 为什么yum 只需要知道软件名即可下载,yum又是去哪里寻找下载的链接?

首先我们要知道评估一个操作系统的好坏就是其生态如何:

生态

  • 社区

  • 文档

  • 人群

  • 问题

  • 配套的软件

所以我们的yum能通过软件名就可以安装是因为拥有系统开发者内置的链接查找的,但是我们有知道这些链接下载都在国外,通过我们国内的一些镜像所提供的链接我们才可以使用的。

bash 复制代码
/etc/yum.repos.d/ yum源配置文件

3. Vim 编辑器的使用

3.1 vim的多模式

3.2 命令模式:快速编辑

  1. 定位到开始:gg

  2. 定位到结尾:n + shift + g = G, n可以指定定位到该行。

  3. 一行定位到开始: ^ ; 一行定位到结尾:$

  4. n + (h,j,k,l) 分别对应上下左右

  5. n + (w,b) w:以单词为单位,向右移动;b:以单词为单位,向左移动

  6. n + yy : 复制,n是复制的行数

  7. n + p : 粘贴到当前行,n是粘贴的行数

  8. u:撤销 ctrl + r:撤销u的操作

  9. n + dd:剪切/删除当前行,n代表数量

  10. n + x:删除光标所在位置字符

  11. n + shift + x:光标右侧不动,左侧删除

  12. shift + ~:大小写切换

  13. n + r :替换光标所在字符,r->目标字符

  14. shift + 3: 选中单词,n:逆向查找

3.3 替换模式

  1. shift + r:批量替换

3.4 底行模式

w/q/!

多窗口模式:vs (另一个文件) , ctrl + ww切换窗口

底行替换

bash 复制代码
%s/str1/str2/g
如果想要将文件中所有 
nihao 替换为 hello 则命令为:  %s/nihao/hello/g 

3.5 视图模式

Ctrl + v : 进入视图模式

进入视图模式,shift+i进入插入模式再次Esc就可以实现批量化批注

3.6 小技巧

bash 复制代码
/* 进入目标行数 */
vim code.c +n  /* n代表行数 */

4. gcc/g++

gcc编译器可以编译C语言和cpp代码,g++只能编译cpp代码

bash 复制代码
gcc file.c/file.cpp -o filename

我们将拿以下文件作为测试内容:

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc hello.c -o hello
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 16
-rwxrwxr-x 1 ouyang ouyang 8440 Dec  7 09:26 hello
-rw-rw-r-- 1 ouyang ouyang  228 Dec  7 09:25 hello.c
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ./hello 
Hello Linux!
Hello Linux!
Hello Linux!
Hello Linux!
Hello Linux!
Hello Linux!
  • 预处理(-E)

E选项是进行程序翻译,在预处理完停下,处理文件的后缀为.i

头文件展开,去注释,宏替换,条件编译。

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc -E hello.c -o hello.i
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 24
-rw-rw-r-- 1 ouyang ouyang   228 Dec  7 09:25 hello.c
-rw-rw-r-- 1 ouyang ouyang 17029 Dec  7 09:31 hello.i
  • 编译(-S)

S选项是进行程序翻译,在编译完停下,处理完的后缀为.s

生成汇编代码

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc -S hello.c -o hello.s
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 28
-rw-rw-r-- 1 ouyang ouyang   228 Dec  7 09:25 hello.c
-rw-rw-r-- 1 ouyang ouyang 17029 Dec  7 09:33 hello.i
-rw-rw-r-- 1 ouyang ouyang   594 Dec  7 09:33 hello.s
  • 汇编(-c)

c(小写)选项是进行程序翻译,在生成机器可识别代码时停下,处理完的后缀为.o

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc -S hello.c -o hello.o
  • 链接(-o)

将目标文件.o链接起来

总结:

选项:-ESc / 后缀名:-iso

5. 理解编译和库的基础概念

5.1 理解条件编译

我们看以下代码:

cpp 复制代码
#include <stdio.h>                                                                                       

int main()
{
    #ifndef M
    printf("no have M\n");
    #else
    printf("have M = %d\n", M);
    #endif
    
    return 0;
  }
/* 无疑以上代码输出的是"no have M\n" */

5.1.1 命令行宏定义

bash 复制代码
-D__ 选项D,__定义宏
bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc Text.c -o Text -DM=20
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ./Text 
have M = 20

预处理--->修改编辑我们的代码

5.1.2 条件编译的用途

  • 区分社区版/专业版,进行代码的动态裁剪,只需要维护一份代码。

  • 内核源代码,对于不同的系统如Linux和Windows,我们都需要支持,都实现,但是在不同的系统执行不同的代码。

  • 开发工具,应用软件。我们是否开会员等等情景

5.1.3 汇编的由来

一开始机器只识别二进制语言,为了方便发明了汇编语言,但是需要一个编译器把汇编语言翻译成机器语言,那么这个这个编译器先由机器语言实现,然后使用汇编语言实现,后续的语言只需要完成从当前语言到汇编语言的翻译即可。

5.2 动静态库

库:一套方法或者数据集,保证基本的接口,功能,加速我们二次开发(如我们是砍树工,那么我们需要买一个砍树机器直接去砍树即可,而不是自己造一个砍树机器再去砍树)。

5.2.1 库的命名方式

bash 复制代码
libc.so 动
libc.a  静
命名规则-> lib (name) .so/.a

动态库:多人共享,一旦丢失,会导致所有程序无法执行!

静态库 :拷贝到本地,一旦链接后不再害怕静态库丢失!

5.2.2 动静态库的对比

  1. 动态库不用拷贝本地,生成的可执行程序体积小。静态库需要拷贝本地,生成的可执行程序体积大。

  2. 可执行程序对动态库的依赖性大。对静态库的依赖性小。

  3. 程序运行,加载到内存,若是静态链接,会产生大量重复的代码。

  4. 动态链接,节省资源(内存和磁盘)

5.2.3 ldd/file/-static指令

bash 复制代码
/* ldd 查看文件是否为动态链接 */
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ldd Text
        linux-vdso.so.1 =>  (0x00007ffee35e8000)
        libc.so.6 => /lib64/libc.so.6 (0x00007ff540889000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff540c56000)

/* file 查看文件状态 */
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ file Text
Text: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
dynamically linked (uses shared libs), 
for GNU/Linux 2.6.32, BuildID[sha1]=3abaa3cc07014cd9ddd60b022a633e82956b6cc0, 
not stripped

/* -static 在链接时执行静态链接*/
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc Text.c -o Text_static -static
-rwxrwxr-x 1 ouyang ouyang   8440 Dec  8 09:38 Text
-rw-rw-r-- 1 ouyang ouyang    131 Dec  8 09:37 Text.c
-rwxrwxr-x 1 ouyang ouyang 861336 Dec  8 10:18 Text_static
我们可以看到动态链接和静态链接之间的文件大小差异很大

尝试链接

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ gcc fun1.o fun2.o main.o -o main
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 48
-rw-rw-r-- 1 ouyang ouyang   75 Dec  8 10:29 fun1.c
-rw-rw-r-- 1 ouyang ouyang   27 Dec  8 10:29 fun1.h
-rw-rw-r-- 1 ouyang ouyang 1496 Dec  8 10:31 fun1.o
-rw-rw-r-- 1 ouyang ouyang   75 Dec  8 10:29 fun2.c
-rw-rw-r-- 1 ouyang ouyang   27 Dec  8 10:29 fun2.h
-rw-rw-r-- 1 ouyang ouyang 1496 Dec  8 10:32 fun2.o
drwxrwxr-x 2 ouyang ouyang 4096 Dec  8 10:21 lib
-rwxrwxr-x 1 ouyang ouyang 8600 Dec  8 10:32 main
-rw-rw-r-- 1 ouyang ouyang   90 Dec  8 10:29 main.c
-rw-rw-r-- 1 ouyang ouyang 1424 Dec  8 10:32 main.o
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ./main
Fun1()Fun2()

链接的本质:把所有的.o文件链接起来

6. make/makefile是什么?

  • make是命令

  • makefile是一个文件

见一见:

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 12
-rw-rw-r-- 1 ouyang ouyang  135 Dec  8 10:39 code.c
drwxrwxr-x 2 ouyang ouyang 4096 Dec  8 10:21 lib
-rw-rw-r-- 1 ouyang ouyang   32 Dec  8 10:40 makefile
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ cat code.c makefile
#include <stdio.h>
int main()
{
    printf("Hello Linux\n");
    printf("Hello Linux\n");
    printf("Hello Linux\n");
    return 0;
}
code:code.c
        gcc code.c -o code
bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ make
gcc code.c -o code
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ll
total 24
-rwxrwxr-x 1 ouyang ouyang 8480 Dec  8 10:40 code
-rw-rw-r-- 1 ouyang ouyang  135 Dec  8 10:39 code.c
drwxrwxr-x 2 ouyang ouyang 4096 Dec  8 10:21 lib
-rw-rw-r-- 1 ouyang ouyang   32 Dec  8 10:40 makefile
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_3]$ ./code
Hello Linux
Hello Linux
Hello Linux

6.1 依赖关系,依赖方法

基础应用:

bash 复制代码
code:code.c
    gcc code.c -o code

.PHONY:clean
clean:
    rm -f code  
bash 复制代码
make
make clean
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ make
gcc code.c -o code
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ ll
total 20
-rwxrwxr-x 1 ouyang ouyang 8480 Dec 11 15:56 code
-rw-rw-r-- 1 ouyang ouyang  136 Dec 11 15:45 code.c
-rw-rw-r-- 1 ouyang ouyang   64 Dec 11 15:54 makefile
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ make clean
rm -f code
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ ll
total 8
-rw-rw-r-- 1 ouyang ouyang 136 Dec 11 15:45 code.c
-rw-rw-r-- 1 ouyang ouyang  64 Dec 11 15:54 makefile
  • ⼀般我们这种clean的⽬标⽂件,我们将它设置为伪⽬标,用.PHONY 修饰,伪目标的特性是,总是被执行的。

什么叫做总是被执行?

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ stat code.c
  File: 'code.c'
  Size: 136               Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d        Inode: 1057217     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/  ouyang)   Gid: ( 1001/  ouyang)
Access: 2024-12-11 15:47:54.587450054 +0800
Modify: 2024-12-11 15:45:44.102708535 +0800
Change: 2024-12-11 15:45:44.102708535 +0800
 Birth: -

⽂件 = 内容 + 属性
Modify: 内容变更,时间更新
Change:属性变更,时间更新
Access:常指的是⽂件最近⼀次被访问的时间。
在Linux的早期版本中,每当⽂件被访问时,其atime都会更新。但这种机制会导致⼤量的IO操作。
具体更新原则,不做过多解释。  

.PHONY:让make忽略源⽂件和可执⾏⽬标⽂件的M时间对比,而忽略这种时间的对比就是叫做总是被执行!

6.2 推导

bash 复制代码
code:code.o
        gcc code.o -o code
code.o:code.s
        gcc -c code.s -o code.o
code.s:code.i
        gcc -S code.i -o code.s
code.i:code.c
        gcc -E code.c -o code.i


.PHONY:clean
clean:
        rm -f *.i *.o *.s code
bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ make
gcc -E code.c -o code.i
gcc -S code.i -o code.s
gcc -c code.s -o code.o
gcc code.o -o code
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ ls
code  code.c  code.i  code.o  code.s  makefile
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ ./code 
Hello Linux
Hello Linux
Hello Linux
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ make clean
rm -f *.i *.o *.s code
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2024_12_8]$ ls
code.c  makefile

make的推导如图栈一般,把不存在的依赖关系的依赖方法存放在栈中,直到从栈顶进行推导,如果在中间的推导过程中,有些依赖关系和依赖方法不存在就停止。

6.3 进度条

  • \r 回车 \n 回车换行

  • 缓冲区问题

    • 我们默认打开三个文件stdin,stdout,stderr,我们使用键盘输入到缓冲区,直到缓冲区刷新屏幕才显示内容。

    • \n 行刷新

    • 程序退出,缓冲区刷新

6.3.1 先做一个倒计时程序

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main()
{
    int cnt = 10;
    while(cnt>=0)
    {
        printf("%-2d\r", cnt);
        fflush(stdout);
        --cnt;
        sleep(1);
    }
    printf("\n");
    return 0;
}

6.3.2 做一个进度条程序

process.h

cpp 复制代码
#pragma once
void Downprocess(double TotalSize, double DownSpeed, double tmpDownSpeed);

process.c

cpp 复制代码
#include "process.h"
#include <string.h>
#include <stdio.h>

#define NUM 101
#define SIGN '='

void Downprocess(double TotalSize, double DownSpeed, double tmpDownSpeed)
{
    char buffer[NUM];
    memset(buffer, 0, sizeof(buffer));
    const char* postsign = "|\\-/";
    int len = strlen(postsign);
    int cnt = (int)(DownSpeed*100/TotalSize);
    int i = 0;
    for(; i <= cnt; ++i)
        buffer[i] = SIGN;
    printf("[%-100s][%-2d%%][%c][当前下载速度:%-.2f]\r", buffer, cnt+1, postsign[cnt%len], tmpDownSpeed);
    fflush(stdout);
}

main.c

cpp 复制代码
#include "process.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>

#define SIZE 1024.0

void Text()
{
    double TotalSize = SIZE;
    double DownSpeed = (double)(rand()%10 + 1);
    double tmpDownSpeed = 0.0;
    while(DownSpeed <= TotalSize)
    {
        /* 下载程序*/
        tmpDownSpeed = (double)(rand()%10 + 1);
        Downprocess(TotalSize, DownSpeed, tmpDownSpeed);
        DownSpeed += tmpDownSpeed;
        usleep(50000);
    }
    printf("\nDownLoad Complete!\n");
}

int main()
{
    srand(time(NULL));
    Text();
    return 0;
}

6.4 makefile的使用拓展

bash 复制代码
SRC=$(shell ls *.c)   # SRC是一个命名,$(shell ls *.c)表示找出当前所有.c后缀的文件
OBJ=$(SRC:.c=.o)      # $(SRC:.c=.o) SRC中所有的.c文件替换成.o
BIN=process.exe     
CC=gcc     
OFLAG=-o
CFLAG=-c
RM=rm -f

$(BIN):$(OBJ)
        @$(CC) $(OFLAG) $@ $^       # $@ 表示BIN  $^ 表示OBJ   
                                    # @符号表示在执行命令时不显示命令本身,只显示命令的输出结果。
        @echo "linking $^ to $@"
%.o:%.c
        @$(CC) $(CFLAG) $<          #  $< 表示将所有的.c文件转变为.o
        @echo "linking $< to $@"

.PHONY:clean
clean:
        $(RM) $(BIN) $(OBJ)

7. Git版本控制器

举例一个场景:

我们在大学生活中,有些科目的老师会要求我们写一些报告,现在我们有小明这个同学,老师要求小明交上一份报告,好了小明写好了第一份初版报告(version-1),老师说格式不行,让小明重写,小明拿回去更改后第二个报告(version-2)又交给老师,老师又觉得小明报告的内容不行,让小明再次回去改,小明拿回去更改后第三份报告(version-3)交给老师,老师说小明你这写的啥啊,你还是把第一次写报告(version-1)给我吧,我给你过。

依照以上场景我们在生活中有时的需求会要求我们对一些文档/程序/等等做多次版本备份,以防出现需求回溯,而git就是这么一个版本控制器,Gitee/Github则是一个平台方便我们可视化地管理我们的版本。

7.1 git的安装

bash 复制代码
# 先检查你的Linux系统是否已经下载,如果没有下载执行以下代码
yum install git

# 查看是否已经安装好
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ ~]$ git --version
git version 1.8.3.1

7.2 创建远端仓库

在Gitee/Github平台创建一个远端仓库,复制URL,使用以下指令克隆一个本地仓库

bash 复制代码
git clone [url]

7.3 git三板斧

7.3.1 git add

将代码放到刚才下载好的⽬录中

bash 复制代码
git add [filename]

将需要⽤git管理的⽂件告知git

7.3.2 git commit

提交本地改动的描述

bash 复制代码
git commit -m "#内容" 

提交的时候应该注明提交日志,描述改动的详细内容.

7.3.3 git push

同步到远端仓库

bash 复制代码
git push

7.4 补充知识

.gitignore内部存放着忽视上传的文件后缀

gitlog 查看提交日志

bash 复制代码
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ linux_-git_-warehouse]$ git log
commit 029dac80c6b2971a21e1b33697a156418cafa3dc
Author: 阳区欠 <2331701342@qq.com>
Date:   Mon Dec 16 19:38:41 2024 +0800

    进度条程序

commit 05fe264b868876a034b83d9205adcc99e1467aee
Author: 阳区欠 <2331701342@qq.com>
Date:   Mon Dec 16 11:34:57 2024 +0000

    Initial commit

8. gdb调试器

这边我使用的是cgdb,相对于gdb好调试一点

8.1 debug模式

我们平时直接执行gcc最后的可执行程序是release模式的代码是不可以调试的,如果想得到可调式的代码程序需要带上-g选项

bash 复制代码
gcc code.c -o code -g

cgdb调试器:

  • 上半部分可以看到调试代码

  • 下半部分可以输入调试指令

8.2 cgdb调试指令

  • quit/q :退出调试

  • break/b 行号:打断点

图中红色字就是断点所在处!

  • run/r :运行程序

    • 如果存在断点,在断点处停下

    • 如果没有断点,跑完整个程序

  • list/l 行数:列出源代码,从头开始,多次列出会记录上次的列出记录往下

cpp 复制代码
(gdb) l 10
5           // 1+...+num
6           int total = 0;
7           int i = 0;
8           while(i <= num)
9           {
10              i++;
11              total += i;
12          }
13          printf("%d\n", total);
14      }
  • list/l 函数:列出我们所需函数模块的代码
cpp 复制代码
(gdb) l TotalAdd
1       #include <stdio.h>
2
3         void TotalAdd(int num)
4       {
5           // 1+...+num
6           int total = 0;
7           int i = 0;
8           while(i <= num)
9           {
10              i++;
  • next/n 逐过程,会跳过函数不进入

  • step/s 逐语句,会进入函数内部

  • info break/b:查看断点信息

bash 复制代码
(gdb) b        19
Breakpoint 1 at 0x40056f: file code.c, line 19.
(gdb) b        12
Breakpoint 2 at 0x40054a: file code.c, line 12.
(gdb) info b
Num     Type           Disp Enb Address            What
1        breakpoint     keep y   0x000000000040056f in main at code.c:19
2        breakpoint     keep y   0x000000000040054a in TotalAdd at code.c:12 
  • finish:执行到当前函数返回
bash 复制代码
(gdb) finish
Run till exit from #0  TotalAdd (num=100) at code.c:6

Breakpoint 2, TotalAdd (num=100) at code.c:13
  • printf/p 表达式:打印表达式的值
bash 复制代码
(gdb) p        i+total
$1 = 5252
  • until 行号:执行到指定行号

  • set var 变量=值

bash 复制代码
(gdb) set var num=10
(gdb) until 13
TotalAdd (num=10) at code.c:13
(gdb) p        i+total
$2 = 77
(gdb) p        num
$3 = 10
  • continue/c:从当前位置连续执行程序

  • delete/d 断点编号:删除断点,如果没有断点编号删除所有断点

  • disable/enable 断点编号:禁用断点/启用断点

  • backtrace/bt:查看当前执行栈的各级函数调用及参数

  • info/i 局部变量:查看局部变量值

  • watch 表达式:实时监视表达式的变化

  • 条件断点:

bash 复制代码
b 9 if i == 30  # 如果i==30时,在行号9的断点执行 

• 条件断点添加常见两种方式:1.新增2.给已有断点追加

• 新增:b⾏号/⽂件名:行号/函数名if i==30(条件)

• 给已有断点追加:condition 2 i==30,其中2是已有断点编号,没有if

相关推荐
Christal_pyy17 分钟前
树莓派4基于Debian GNU/Linux 12 (Bookworm)添加多个静态ipv4网络
linux·网络·debian
csbDD1 小时前
2025年网络安全(黑客技术)三个月自学手册
linux·网络·python·安全·web安全
李狗蛋儿啊1 小时前
zero自动化框架搭建---Git安装详解
运维·git·自动化
小金的学习笔记2 小时前
如何在本地和服务器新建mysql用户和密码
运维·服务器·mysql
EasyNVR2 小时前
EasyRTC智能硬件:实时畅联、沉浸互动、消音护航
运维·服务器·网络·安全·音视频·webrtc·p2p
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
Natsuagin3 小时前
轻松美化双系统启动界面与同步时间设置(Windows + Ubuntu)
linux·windows·ubuntu·grub
人工干智能4 小时前
科普:“git“与“github“
git·github
我们的五年4 小时前
【Linux网络编程】应用层协议HTTP(请求方法,状态码,重定向,cookie,session)
linux·网络·http
xing.yu.CTF5 小时前
Web入侵实战分析-常见web攻击类应急处置实验2
运维·服务器·windows·web安全·apache·php漏洞·phpstudy后门漏洞