目录
-
- [1. 引言](#1. 引言)
- [2. 基础开发工具](#2. 基础开发工具)
- [3. 软件包管理器](#3. 软件包管理器)
-
- [3.1 什么是软件包](#3.1 什么是软件包)
- [3.2 Linux 软件生态](#3.2 Linux 软件生态)
- [3.3 yum 具体操作](#3.3 yum 具体操作)
-
- [3.3.1 查看软件包](#3.3.1 查看软件包)
- [3.3.2 安装软件](#3.3.2 安装软件)
- [3.3.3 卸载软件](#3.3.3 卸载软件)
- [3.3.4 注意事项](#3.3.4 注意事项)
- [3.4 安装源](#3.4 安装源)
- [4. 编辑器 Vim](#4. 编辑器 Vim)
-
- [4.1 Linux 编辑器 - vim 使用](#4.1 Linux 编辑器 - vim 使用)
- [4.2 vim 的基本概念](#4.2 vim 的基本概念)
- [4.3 vim 的基本操作](#4.3 vim 的基本操作)
- [4.4 vim 正常模式命令集](#4.4 vim 正常模式命令集)
- [4.5 vim 末行模式命令集](#4.5 vim 末行模式命令集)
- [4.6 vim 操作总结](#4.6 vim 操作总结)
- [4.7 简单 vim 配置(了解)](#4.7 简单 vim 配置(了解))
- [5. 版本控制 Git](#5. 版本控制 Git)
-
- [Git 三板斧:add、commit、push 实战](#Git 三板斧:add、commit、push 实战)
- [6. 调试器 gdb/cgdb](#6. 调试器 gdb/cgdb)
-
- [6.1 gdb 简介](#6.1 gdb 简介)
- [6.2 调试实战:计算阶乘](#6.2 调试实战:计算阶乘)
-
- [6.2.1 准备调试程序](#6.2.1 准备调试程序)
- [6.2.2 编译时添加调试信息](#6.2.2 编译时添加调试信息)
- [6.2.3 启动 gdb](#6.2.3 启动 gdb)
- [6.2.4 设置断点](#6.2.4 设置断点)
- [6.2.5 运行程序](#6.2.5 运行程序)
- [6.2.6 单步执行](#6.2.6 单步执行)
- [6.2.7 打印变量值](#6.2.7 打印变量值)
- [6.2.8 条件断点](#6.2.8 条件断点)
- [6.2.9 查看调用栈](#6.2.9 查看调用栈)
- [6.2.10 监视变量变化](#6.2.10 监视变量变化)
- [6.2.11 退出调试](#6.2.11 退出调试)
- [6.3 完整调试会话示例](#6.3 完整调试会话示例)
- [6.4 gdb 常用命令速查表](#6.4 gdb 常用命令速查表)
1. 引言
Linux 开发环境是每一位后端工程师的必修课。从软件包管理、编辑器使用、编译器操作、自动化构建、版本控制到调试器,系统性地带你掌握 Linux 基础开发工具链。
内容概览
- 软件包管理器(yum/apt):掌握 Linux 软件的安装、卸载与源配置
- 编辑器 Vim:熟练使用三种模式及常用操作命令
- 版本控制 Git:掌握本地提交与远程推送的三板斧操作
- 调试器 gdb/cgdb:学会断点调试、变量监视与条件断点等核心技巧
2. 基础开发工具
学习目标
- 学习 yum 工具,进行软件安装
- 掌握 vim 编辑器使用,学会 vim 的简单配置
- 学习 git 命令行的简单操作,能够将代码上传到 Gitee 上
- 掌握简单 gdb 使用于调试
3. 软件包管理器
3.1 什么是软件包
在 Linux 下安装软件,一个通常的办法是下载到程序的源代码,并进行编译,得到可执行程序。但是这样太麻烦了,于是有些人把一些常用的软件提前编译好,做成软件包(可以理解成 Windows 上的安装程序)放在一个服务器上,通过包管理器可以很方便的获取到这个编译好的软件包,直接进行安装。
软件包和软件包管理器,就好比 "App" 和 "应用商店" 这样的关系。
- yum(Yellow Dog Updater, Modified)是 Linux 下非常常用的一种包管理器,主要应用在 Fedora、RedHat、CentOS 等发行版上。
- Ubuntu:主要使用 apt(Advanced Package Tool)作为其包管理器。apt 同样提供了自动解决依赖关系、下载和安装软件包的功能。
3.2 Linux 软件生态
以下是国内 Linux 软件安装源的官方链接:
- 阿里云官方镜像站
- 官方链接:https://developer.aliyun.com/mirror/
- 阿里云提供了丰富的 Linux 发行版镜像,包括 CentOS, Ubuntu, Debian 等,用户可以通过该镜像站快速下载和更新软件包。
- 清华大学开源软件镜像站
- 官方链接:https://mirrors.tuna.tsinghua.edu.cn/
- 清华大学镜像站提供了多种 Linux 发行版的镜像,以及 Python, Perl, Ruby 等编程语言的扩展包。
- 中国科学技术大学开源镜像站
- 官方链接:http://mirrors.ustc.edu.cn/
- 中科大镜像站提供了多种 Linux 发行版的镜像,以及常用的编程语言和开发工具。
- 北京交通大学自由与开源软件镜像站
- 官方链接:https://mirror.bjtu.edu.cn/
- 北交大镜像站提供了多种 Linux 发行版的镜像,以及相关的软件仓库和工具。
- 中国科学院软件研究所镜像站(ISCAS)
- 官方链接:http://mirror.iscas.ac.cn/
- ISCAS 镜像站提供了多种 Linux 发行版、编程语言和开发工具的镜像。
- 上海交通大学开源镜像站
- 官方链接:https://ftp.sjtu.edu.cn/
- 上海交大镜像站提供了丰富的 Linux 软件资源,包括多种发行版的镜像和软件仓库。
- 网易开源镜像站
- 官方链接:http://mirrors.163.com/
- 网易镜像站提供了多种 Linux 发行版的镜像,以及相关的软件仓库和工具。
此外,还有一些其他的国内镜像源,如搜狐开源镜像站等,但可能由于时间变化或政策调整,部分镜像站的链接或状态可能有所变动。因此,建议用户在使用前访问官方网站或咨询相关社区以获取最新的信息和帮助。
在 CentOS/RHEL 系 Linux 上,安装并启用一个叫 EPEL 的 "额外软件源",以后就能装很多官方源里没有的软件了。
bash
sudo yum install -y epel-release
3.3 yum 具体操作
3.3.1 查看软件包
通过 yum list 命令可以罗列出当前一共有哪些软件包。由于包的数量可能非常之多,这里我们需要使用 grep 命令只筛选出我们关注的包。例如:
bash
# CentOS
$ yum list | grep lrzsz
lrzsz.x86_64 0.12.20-36.el7 @base
# Ubuntu
$ apt search lrzsz
Sorting... Done
Full Text Search... Done
cutecom/focal 0.30.3-1build1 amd64
Graphical serial terminal, like minicom
lrzsz/focal,now 0.12.21-10 amd64 [installed]
Tools for zmodem/xmodem/ymodem file transfer
$ apt show lrzsz
Package: lrzsz
Version: 0.12.21-10
Priority: optional
Section: universe/comm
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Martin A. Godisch <godisch@debian.org>
...
注意事项:
- 软件包名称:主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。
- "x86_64" 后缀表示 64 位系统的安装包,"i686" 后缀表示 32 位系统安装包。选择包时要和系统匹配。
- "el7" 表示操作系统发行版的版本。"el7" 表示的是 CentOS 7 / RedHat 7。"el6" 表示 CentOS 6 / RedHat 6。
- 最后一列,base 表示的是 "软件源" 的名称,类似于 "小米应用商店", "华为应用商店" 这样的概念。
3.3.2 安装软件
通过 yum,我们可以通过很简单的一条命令完成 gcc 的安装。
bash
# CentOS
$ sudo yum install -y lrzsz
# Ubuntu
$ sudo apt install -y lrzsz
- yum/apt 会自动找到都有哪些软件包需要下载,这时候敲 "y" 确认安装。
- 出现 "complete" 字样或者中间未出现报错,说明安装完成。
注意事项:
- 安装软件时由于需要向系统目录中写入内容,一般需要
sudo或者切到root账户下才能完成。 - yum/apt 安装软件只能一个装完了再装另一个。正在 yum/apt 安装一个软件的过程中,如果再尝试用 yum/apt 安装另外一个软件,yum/apt 会报错。
- 如果 yum/apt 报错,请自行询问AI。
3.3.3 卸载软件
仍然是一条命令:
bash
# CentOS
sudo yum remove [-y] lrzsz
# Ubuntu
sudo apt remove [-y] lrzsz
3.3.4 注意事项
关于 yum/apt 的所有操作必须保证主机(虚拟机)网络畅通!可以通过 ping 指令验证:
bash
ping www.baidu.com
当然 yum/apt 也能离线安装,但是和我们当前无关,暂不关心。
3.4 安装源
CentOS 安装源路径:
bash
$ ll /etc/yum.repos.d/
total 16
-rw-r--r-- 1 root root 676 Oct 8 20:47 CentOS-Base.repo # 标准源
-rw-r--r-- 1 root root 230 Aug 27 10:31 epel.repo # 扩展源
# 安装扩展源,方便课堂演示
# $ sudo yum install -y epel-release
Ubuntu 安装源路径:
bash
$ cat /etc/apt/sources.list # 标准源
$ ll /etc/apt/sources.list.d/ # 扩展源
# ubuntu 安装扩展源,就结合未来具体场景
更新安装源,现场说明原理即可。云服务器不用考虑,因为软件源都是国内的了。
4. 编辑器 Vim
4.1 Linux 编辑器 - vim 使用
vi/vim 的区别简单点来说,它们都是多模式编辑器,不同的是 vim 是 vi 的升级版本,它不仅兼容 vi 的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于 x window, mac os, windows。这里我们统一按照 vim 来进行讲解。
4.2 vim 的基本概念
vim 的三种模式(其实有好多模式,目前掌握这 3 种即可),分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:
- 正常/普通/命令模式(Normal mode):控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入 Insert mode 下,或者到 last line mode。
- 插入模式(Insert mode):只有在 Insert mode 下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
- 末行模式(last line mode) :文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。在命令模式下,
shift+:即可进入该模式。要查看你的所有模式:打开 vim,底行模式直接输入:help vim-modes。我这里一共有 12 种模式:six BASIC modes 和 six ADDITIONAL modes。
4.3 vim 的基本操作
-
进入 vim,在系统提示符号输入 vim 及文件名称后,就进入 vim 全屏幕编辑画面:
bash$ vim test.c -
不过有一点要特别注意,就是你进入 vim 之后,是处于 正常模式,你要切换到 插入模式 才能够输入文字。
-
正常模式 切换至 插入模式
- 输入
a - 输入
i - 输入
o
- 输入
-
插入模式 切换至 正常模式
- 目前处于 插入模式,就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到 正常模式 再删除文字。当然,也可以直接删除。
-
正常模式 切换至 末行模式
- 「shift + ;」,其实就是输入「:」
-
退出 vim 及保存文件 ,在 正常模式 下,按一下「:」冒号键进入「Last line mode」,例如:
:w(保存当前文件):wq(输入「wq」,存盘并退出 vim):q!(输入 q!,不存盘强制退出 vim)
4.4 vim 正常模式命令集
- 插入模式
- 按「i」切换进入插入模式「insert mode」,按 "i" 进入插入模式后是从光标当前位置开始输入文件;
- 按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
- 按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。
- 从插入模式切换为命令模式
- 按「ESC」键。
- 移动光标
- vim 可以直接用键盘上的光标来上下左右移动,但正规的 vim 是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格。
- 按「G」:移动到文章的最后
- 按「$」:移动到光标所在行的 "行尾"
- 按「^」:移动到光标所在行的 "行首"
- 按「w」:光标跳到下个字的开头
- 按「e」:光标跳到下个字的字尾
- 按「b」:光标回到上个字的开头
- 按「#l」:光标移到该行的第 # 个位置,如:5l, 56l
- 按[gg]:进入到文本开始
- 按[shift + g]:进入文本末端
- 按「ctrl」+「b」:屏幕往 "后" 移动一页
- 按「ctrl」+「f」:屏幕往 "前" 移动一页
- 按「ctrl」+「u」:屏幕往 "后" 移动半页
- 按「ctrl」+「d」:屏幕往 "前" 移动半页
- 删除文字
- 「x」:每按一次,删除光标所在位置的一个字符
- 「#x」:例如,「6x」表示删除光标所在位置的 "后面(包含自己在内)" 6 个字符
- 「X」:大写的 X,每按一次,删除光标所在位置的 "前面" 一个字符
- 「#X」:例如,「20X」表示删除光标所在位置的 "前面" 20 个字符
- 「dd」:删除光标所在行
- 「#dd」:从光标所在行开始删除 # 行
- 复制
- 「yw」:将光标所在之处到字尾的字符复制到缓冲区中。
- 「#yw」:复制 # 个字到缓冲区
- 「yy」:复制光标所在行到缓冲区。
- 「#yy」:例如,「6yy」表示拷贝从光标所在的该行 "往下数" 6 行文字。
- 「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与 "y" 有关的复制命令都必须与 "p" 配合才能完成复制与粘贴功能。
- 替换
- 「r」:替换光标所在处的字符。
- 「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
- 撤销上一次操作
- 「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次 "u" 可以执行多次回复。
- 「ctrl + r」:撤销的恢复
- 更改
- 「cw」:更改光标所在处的字到字尾处
- 「c#w」:例如,「c3w」表示更改 3 个字
- 跳至指定的行
- 「ctrl」+「g」列出光标所在行的行号。
- 「#G」:例如,「15G」,表示移动光标至文章的第 15 行行首。
4.5 vim 末行模式命令集
在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。
- 列出行号
- 「set nu」:输入「set nu」后,会在文件中的每一行前面列出行号。
- 跳到文件中的某一行
- 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字 15,再回车,就会跳到文章的第 15 行。
- 查找字符
- 「/关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。
- 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止。
- 问题:/ 和 ? 查找有和区别?操作实验一下。
- 保存文件
- 「w」:在冒号输入字母「w」就可以将文件保存起来。
- 离开 vim
- 「q」:按「q」就是退出,如果无法离开 vim,可以在「q」后跟一个「!」强制离开 vim。
- 「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
4.6 vim 操作总结
- 三种模式
- 正常模式
- 插入模式
- 底行模式
- 我们一共有 12 种总模式,大家下来可以研究一下。
- vim 操作
- 打开,关闭,查看,查询,插入,删除,替换,撤销,复制等等操作。
- 练习:当堂口头模式切换练习。
4.7 简单 vim 配置(了解)
配置文件的位置
- 在目录
/etc/下面,有个名为 vimrc 的文件,这是系统中公共的 vim 配置文件,对所有用户都有效。 - 而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:".vimrc"。例如,/root 目录下,通常已经存在一个 .vimrc 文件,如果不存在,则创建之。
- 切换用户成为自己执行
su,进入自己的主工作目录,执行cd ~。 - 打开自己目录下的 .vimrc 文件,执行
vim .vimrc。
常用配置选项,用来测试
- 设置语法高亮:
syntax on - 显示行号:
set nu - 设置缩进的空格数为 4:
set shiftwidth=4
使用插件
要配置好看的 vim,原生的配置可能功能不全,可以选择安装插件来完善配置,保证用户是你要配置的用户,接下来:
- 安装 TagList 插件
我比较推荐下面这个一键化部署(只能Centos7 x86_64系统哈)

5. 版本控制 Git
Git 三板斧:add、commit、push 实战
下面演示从零开始,将一个本地项目初始化、添加文件、提交并推送到远程仓库(如 GitHub)的完整流程。
bash
# 1. 初始化本地仓库
$ cd ~/my_project # 进入项目目录
$ git init # 在当前目录下创建 .git 仓库
# 输出:Initialized empty Git repository in /home/user/my_project/.git/
# 2. 配置用户信息(首次使用 Git 时需要)
$ git config --global user.name "Your Name"
$ git config --global user.email "your_email@example.com"
# 3. 创建或修改文件
$ echo "# My Project" > README.md # 创建一个 README 文件
$ echo "print('Hello Git')" > main.py
# 4. 查看当前仓库状态
$ git status
# 输出示例:
# On branch master
# No commits yet
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# README.md
# main.py
# 5. 第一板斧:git add ------ 将文件添加到暂存区
$ git add README.md main.py # 添加指定文件
# 或一次性添加所有变更:git add .
# 再次查看状态,文件变为绿色(已暂存)
$ git status
# 输出示例:
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
# new file: README.md
# new file: main.py
# 6. 第二板斧:git commit ------ 将暂存区内容提交到本地仓库
$ git commit -m "feat: 初始化项目,添加 README 和主程序"
# 输出示例:
# [master (root-commit) a1b2c3d] feat: 初始化项目,添加 README 和主程序
# 2 files changed, 2 insertions(+)
# create mode 100644 README.md
# create mode 100644 main.py
# 7. 查看提交历史
$ git log --oneline
# 输出示例:
# a1b2c3d (HEAD -> master) feat: 初始化项目,添加 README 和主程序
# 8. 第三板斧:git push ------ 推送到远程仓库(如 GitHub)
# 8.1 先在 GitHub 上创建一个空仓库(不要勾选 README/.gitignore),复制仓库 URL
# 例如:https://github.com/your_username/my_project.git
# 8.2 添加远程仓库地址
$ git remote add origin https://github.com/your_username/my_project.git
# 8.3 推送本地 master 分支到远程仓库
$ git push -u origin master
# 输入 GitHub 用户名和 Personal Access Token(密码)
# 输出示例:
# Enumerating objects: 3, done.
# Counting objects: 100% (3/3), done.
# Writing objects: 100% (3/3), 232 bytes | 232.00 KiB/s, done.
# Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
# To https://github.com/your_username/my_project.git
# * [new branch] master -> master
# Branch 'master' set up to track remote branch 'master' from 'origin'.
# 9. 后续日常操作:修改文件 → git add → git commit → git push
$ echo "print('第二次提交')" >> main.py # 修改文件
$ git add main.py
$ git commit -m "feat: 添加第二行输出"
$ git push # 第二次及以后推送无需再指定远程和分支
命令总结:
| 步骤 | 命令 | 作用 |
|---|---|---|
| 第一板斧 | git add <文件> |
将工作区的修改添加到暂存区 |
| 第二板斧 | git commit -m "说明" |
将暂存区内容提交到本地仓库,生成一个版本 |
| 第三板斧 | git push |
将本地仓库的提交推送到远程仓库(如 GitHub) |
提示 :推送前需先在 GitHub 上创建空仓库并获取仓库 URL;首次推送时使用
-u参数建立本地分支与远程分支的追踪关系,后续只需git push即可。
6. 调试器 gdb/cgdb
6.1 gdb 简介
gdb(GNU Debugger)是 Linux 下最常用的 C/C++ 程序调试器,支持断点设置、单步执行、变量监视、调用栈查看等核心功能。cgdb 是 gdb 的终端界面增强版,在 gdb 基础上增加了代码窗口,使用体验更友好。
6.2 调试实战:计算阶乘
下面以一个计算阶乘的 C 程序为例,演示 gdb 的完整调试流程。
6.2.1 准备调试程序
首先编写一个简单的阶乘程序 factorial.c:
c
#include <stdio.h>
// 递归计算 n 的阶乘
int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
int main() {
int num = 5;
int result = factorial(num);
printf("%d! = %d\n", num, result);
return 0;
}
6.2.2 编译时添加调试信息
使用 -g 选项编译,生成包含调试符号的可执行文件:
bash
$ gcc -g -o factorial factorial.c
# -g 选项告诉编译器在可执行文件中嵌入调试信息(变量名、行号等)
# 不加 -g 则无法在 gdb 中查看源码和变量
6.2.3 启动 gdb
bash
$ gdb factorial
# 进入 gdb 交互界面,显示如下信息:
# GNU gdb (GDB) ...
# Reading symbols from factorial...
# (gdb) ← 这是 gdb 的命令提示符
6.2.4 设置断点
bash
(gdb) break main
# 在 main 函数入口处设置断点
# 输出:Breakpoint 1 at 0x...: file factorial.c, line 12.
(gdb) break factorial
# 在 factorial 函数入口处设置断点
# 输出:Breakpoint 2 at 0x...: file factorial.c, line 5.
(gdb) break factorial.c:8
# 在 factorial.c 的第 8 行(return n * factorial(n - 1);)设置断点
# 输出:Breakpoint 3 at 0x...: file factorial.c, line 8.
(gdb) info breakpoints
# 查看所有已设置的断点
# 输出示例:
# Num Type Disp Enb Address What
# 1 breakpoint keep y 0x... in main at factorial.c:12
# 2 breakpoint keep y 0x... in factorial at factorial.c:5
# 3 breakpoint keep y 0x... in factorial.c:8
6.2.5 运行程序
bash
(gdb) run
# 启动程序,程序会在第一个断点处暂停
# 输出:
# Breakpoint 1, main () at factorial.c:12
# 12 int num = 5;
6.2.6 单步执行
bash
(gdb) next # 单步执行,不进入函数内部(相当于逐过程)
# 输出:
# 13 int result = factorial(num);
(gdb) step # 单步执行,进入函数内部(相当于逐语句)
# 进入 factorial 函数:
# Breakpoint 2, factorial (n=5) at factorial.c:5
# 5 if (n <= 1) {
6.2.7 打印变量值
bash
(gdb) print n
# 输出:$1 = 5
(gdb) print num
# 输出:$2 = 5
(gdb) print &n
# 输出:$3 = (int *) 0x7fffffffe...
(gdb) display n
# 每次暂停时自动显示 n 的值(自动变量监视)
# 输出:1: n = 5
6.2.8 条件断点
bash
# 设置条件断点:当 n == 3 时暂停
(gdb) break factorial if n == 3
# 输出:Breakpoint 4 at 0x...: file factorial.c, line 5.
# 或者修改已有断点的条件
(gdb) condition 3 n == 3
# 将 3 号断点(factorial.c:8)的条件设为 n == 3
(gdb) continue
# 继续执行,直到遇到条件满足的断点
# 当递归到 n=3 时暂停:
# Breakpoint 4, factorial (n=3) at factorial.c:5
# 5 if (n <= 1) {
6.2.9 查看调用栈
bash
(gdb) backtrace
# 查看当前函数调用栈(从 main 到当前递归层)
# 输出示例:
# #0 factorial (n=3) at factorial.c:5
# #1 0x... in factorial (n=4) at factorial.c:8
# #2 0x... in factorial (n=5) at factorial.c:8
# #3 0x... in main () at factorial.c:13
(gdb) frame 1
# 切换到第 1 层调用栈(n=4 的那一层)
# 输出:
# #1 0x... in factorial (n=4) at factorial.c:8
# 8 return n * factorial(n - 1);
(gdb) print n
# 输出:$4 = 4
6.2.10 监视变量变化
bash
(gdb) watch n
# 当 n 的值发生变化时暂停
# 输出:Hardware watchpoint 5: n
(gdb) continue
# 每次 n 变化时都会暂停并显示旧值和新值
6.2.11 退出调试
bash
(gdb) quit
# 退出 gdb,如果程序仍在运行会询问是否终止
6.3 完整调试会话示例
下面是一次完整的调试会话,从启动到结束:
bash
$ gcc -g -o factorial factorial.c
$ gdb factorial
(gdb) break main
(gdb) break factorial if n == 3
(gdb) run
# 停在 main 函数
(gdb) next
# 执行到 factorial(num) 调用前
(gdb) step
# 进入 factorial 函数,n=5
(gdb) continue
# 递归到 n=3 时暂停(条件断点触发)
(gdb) print n
# $1 = 3
(gdb) backtrace
# 查看调用栈
(gdb) delete 3
# 删除 3 号断点
(gdb) continue
# 继续执行到程序结束
(gdb) quit
6.4 gdb 常用命令速查表
| 命令 | 缩写 | 作用 |
|---|---|---|
break |
b |
设置断点(可按函数名、行号、文件名:行号) |
run |
r |
启动程序 |
next |
n |
单步执行(不进入函数) |
step |
s |
单步执行(进入函数) |
continue |
c |
继续执行到下一个断点 |
print |
p |
打印变量或表达式的值 |
display |
--- | 每次暂停时自动显示指定变量 |
backtrace |
bt |
查看函数调用栈 |
frame |
f |
切换到指定调用栈帧 |
watch |
--- | 监视变量,值变化时暂停 |
condition |
--- | 为断点设置条件 |
info breakpoints |
i b |
查看所有断点 |
delete |
d |
删除断点 |
quit |
q |
退出 gdb |
提示 :cgdb 是 gdb 的增强版,安装后使用
cgdb factorial启动,上方显示代码窗口,下方是 gdb 命令行,按Esc可切换到代码窗口并用j/k浏览源码,按i返回命令行模式。