GDB & LLDB 调试 C/C++ 指南

文档概述

本文档完整、系统、详细介绍 GDB(GNU 调试器,Linux 首选) 和 LLDB(LLVM 调试器,macOS 首选) 调试 C/C++ 代码的全流程,包含完整命令、简写命令、功能说明、使用场景、实战案例,所有核心命令均以表格形式清晰呈现,适合新手入门、日常开发、问题排查。

适用平台:Linux(GDB)、macOS(GDB/LLDB)、WSL(GDB)

适用语言:C / C++

核心用途:崩溃排查、逻辑错误、变量异常、内存问题、多线程调试


一、调试前置:编译带调试符号的程序

所有调试必须先执行这一步! 否则调试器无法识别代码行、变量、函数。

编译命令

# C 语言
gcc -g -O0 test.c -o test

# C++ 语言
g++ -g -O0 test.cpp -o test

# Clang 编译(LLDB 推荐)
clang -g -O0 test.c -o test
  • -g:生成调试符号(必备)
  • -O0:关闭编译器优化,保证调试精准

二、GDB 使用手册(Linux 主流)

1. GDB 启动方式

启动命令功能
gdb ./test调试可执行文件
gdb -p PID附加到正在运行的进程
gdb ./test core.xxx调试崩溃转储文件

2. GDB 命令表

(1)程序运行控制

完整命令简写命令功能说明
runr启动程序,运行到断点处停止
continuec从断点处继续运行程序
nextn单步执行,不进入函数内部
steps单步执行,进入函数内部
finishfin执行完当前函数并跳出
until 行号u 行号直接运行到指定代码行
killk终止当前调试的程序
quitq退出 GDB 调试器

(2)断点管理

完整命令简写命令功能说明
break 行号b 行号在当前文件指定行打断点
break 文件名:行号b 文件名:行号在指定文件的指定行打断点
break 函数名b 函数名在函数入口处打断点
break 行号 if 条件b 行号 if 条件条件断点(满足条件才触发)
info breakpointsi b查看所有断点
delete 断点编号d 编号删除指定编号断点
disable 断点编号—禁用断点(不删除)
enable 断点编号—启用断点
clear 行号—删除指定行的断点

(3)变量 & 内存查看

完整命令简写命令功能说明
print 变量p 变量打印变量值
print *指针p *指针打印指针指向的数据
print 数组@长度p arr@5打印数组前 N 个元素
display 变量—每次单步自动打印变量
undisplay 编号—取消自动打印
set variable 变量=值set var=值运行时修改变量值
x/格式 地址—查看内存数据(x/nfu 格式)
info locals—查看当前函数所有局部变量
info args—查看当前函数参数

(4)堆栈追踪

完整命令简写命令功能说明
backtracebt查看函数调用堆栈
frame 编号f 编号切换到指定堆栈帧
up—切换到上一层堆栈
down—切换到下一层堆栈

(5)高级调试

完整命令简写命令功能说明
listl显示当前代码上下文
list 函数名l 函数查看指定函数代码
watch 变量—数据断点(变量被修改时暂停)
info threads—查看所有线程
thread 编号—切换到指定线程
disassemble—查看汇编代码

三、LLDB 使用手册(macOS 原生)

LLDB 是 macOS /iOS 开发默认调试器,语法与 GDB 高度兼容,支持 GDB 简写命令,同时拥有更规范的完整命令。

1. LLDB 启动方式

启动命令功能
lldb ./test调试可执行文件
lldb -p PID附加到运行中进程

2. LLDB 命令表

(1)程序运行控制

完整命令简写命令功能说明
runr启动程序
continuec继续运行
nextn单步跳过(不进函数)
steps单步进入(进函数)
finishfin跳出当前函数
until 行号u 行号运行到指定行
quitq退出 LLDB

(2)断点管理

完整命令简写命令功能说明
breakpoint set --line 行号b 行号在当前行设置断点
breakpoint set --file 文件名 --line 行号b 文件:行号在指定文件行设置断点
breakpoint set --name 函数名b 函数名在函数入口打断点
breakpoint set --line 行号 --condition 条件b 行号 if 条件条件断点
breakpoint list—查看所有断点
breakpoint delete 编号—删除断点
breakpoint disable 编号—禁用断点
breakpoint enable 编号—启用断点

(3)变量 & 内存查看

完整命令简写命令功能说明
print 变量p 变量打印变量
expression 变量=值expr var=值运行时修改变量
frame variablefr v查看所有局部变量
memory read 地址memory read &var查看内存数据
watchpoint set variable 变量—数据断点(修改变量时暂停)

(4)堆栈追踪

完整命令简写命令功能说明
thread backtracebt查看调用堆栈
frame select 编号f 编号切换堆栈帧
up—上一层堆栈
down—下一层堆栈

(5)高级调试

完整命令简写命令功能说明
listl显示源代码
thread list—查看所有线程
thread select 编号—切换线程
disassemble—查看汇编

四、GDB vs LLDB 命令对照表

功能GDB 完整命令GDB 简写LLDB 完整命令LLDB 简写
运行程序runrrunr
继续运行continueccontinuec
单步跳过nextnnextn
单步进入stepssteps
跳出函数finishfinfinishfin
运行到行until 行号uuntil 行号u
行断点break 行号bbreak set --lineb
函数断点break 函数bbreak set -nb
查看断点info breaki bbreak list—
删除断点deletedbreak delete—
打印变量printpprintp
修改变量set var=值—expr var=值—
查看堆栈backtracebtthread backtracebt
切换堆栈frame 编号fframe selectf
查看局部变量info locals—frame variablefr v
数据断点watch 变量—watchpoint set—
退出quitqquitq

五、调试实战

1. 编译

gcc -g test.c -o test

2. 启动调试器

gdb ./test
# 或
lldb ./test

3. 打断点

b main
b 15

4. 运行程序

r

5. 调试

n  # 单步跳过
s  # 单步步入
p 变量  # 查看值
bt  # 查崩溃
c  # 继续运行

6. 退出

q

六、排查崩溃(Segmentation fault)

  1. 编译加 -g
  2. 运行调试器
  3. 程序崩溃后输入:
bt

即可直接定位崩溃代码行。