往期内容回顾
一、 Linux 下的调试工具 GDB
一、为什么要学习 GDB?
调试是开发不可或缺的环节,无论是初学编程还是开发大型项目,都难免会遇到程序崩溃、逻辑错误、死循环等问题。
GDB(GNU Debugger)是 Linux/Unix 下最常用的命令行调试工具,能帮助你精确定位问题所在。
学会用 GDB,能极大提升排错效率,节省大量调试时间。
对于理解程序运行机制、学习底层细节也很有帮助。
二、什么是 GDB?
GDB 是 GNU 项目下的调试器,用于调试用 C、C++、Fortran 等语言编写的程序。
它允许你:
运行程序并监控执行过程
设置断点暂停程序
查看变量和内存内容
-
单步执行代码
跟踪调用栈
修改变量值
GDB 是基于命令行的,但也有很多图形前端(如 DDD、Nemiver、Eclipse 等)用来提升交互体验
三、GDB 的基本使用
1. 编译带调试信息的程序
为了让 GDB 能查看源码信息,必须在编译时加上 -g 参数:
gcc -g hello.c -o hello
原因:gcc/g++默认在编译文件的时候,文件的版本为release版本,无法进行调试,在编译时必须要 加上 -g允许gdb查看源码才能进入调试模式。
gdb ./hello
2. 常用命令示例
命令 |
说明 |
---|---|
run / r |
启动程序 |
break main / b main |
在 main 函数设置断点 |
break 文件名:行号 |
在指定行设置断点 |
next / n |
单步执行下一行(不进入函数内部) |
step / s |
单步执行,进入函数内部 |
continue / c |
继续运行直到下一个断点或程序结束 |
print 变量名 / p |
打印变量值 |
info locals |
查看当前函数所有局部变量 |
backtrace / bt |
查看调用栈 |
list / l |
查看源码(当前行附近) |
quit / q |
退出 GDB |
3、调试流程示例
(gdb) break main # 设置断点
(gdb) break delete num # 删除第num个断点
(gdb) run # 运行程序
(gdb) next # 执行下一行
(gdb) print x # 打印变量 x
(gdb) continue # 继续执行
(gdb) backtrace # 查看调用栈
(gdb) quit # 退出(gdb) p &x #查看变量的地址
(gdb) display x #变量的常显示
(gdb)until num #跳出循环至下一次有效代码行num
(gdb) set var sum = 10 # 修改变量值
(gdb)info locals #查看局部变量
四、总结
优点 |
适用场景 |
---|---|
免费、开源、功能强大 |
C/C++ 程序调试 |
支持断点、单步执行、变量查看 |
定位程序崩溃和逻辑错误 |
支持多线程、远程调试 |
复杂项目调试 |
有丰富的命令集和脚本支持 |
自动化调试流程 |
二、macos下的调试工具LLDB
一、macOS 的 LLDB 简介
1. 什么是 LLDB?
LLDB 是 Apple 推出的调试器,属于 LLVM 项目的一部分。
它是 macOS 和 iOS 平台上的默认调试器,随 Xcode 工具链安装。
LLDB 设计现代化,支持最新的编译器生成的调试信息(特别是 Clang/LLVM 生成的 DWARF)。
原生支持 ARM64 (Apple Silicon) 架构,支持多线程、异步编程调试。
2. LLDB 与 GDB 的关系
LLDB 最初是为了替代 GDB 在苹果生态的地位而开发的。
LLDB 和 GDB 在命令行风格上有很多相似之处,但内部架构不同。
LLDB 使用现代 C++ 编写,集成 LLVM,调试效率和对新架构的支持更好。
GDB 作为 GNU 项目,历史悠久,跨平台广泛,但 macOS 上对最新 Apple 硬件和编译器支持不如 LLDB。
二、macOS LLDB 的安装和启动
默认已经安装:macOS 自带 Xcode 或者 Xcode 命令行工具后,会自动安装 LLDB。
启动 LLDB:
lldb <program>
进入交互命令行界面,等待用户输入命令
三、LLDB 常用命令详解
任务 |
LLDB 命令示例 |
说明 |
GDB 对应命令 |
---|---|---|---|
启动程序 |
run |
运行程序 |
run / r |
设置函数断点 |
breakpoint set -n main 或 b main |
在函数名 main 处设置断点 |
break main |
设置行断点 |
breakpoint set -f file.c -l 42 或 b file.c:42 |
在文件 file.c 的第 42 行设置断点 |
break file.c:42 |
列出断点 |
breakpoint list 或 br list |
列出所有断点 |
info break |
删除断点 |
breakpoint delete 1 |
删除断点编号 1 |
delete 1 |
单步执行(不进入函数) |
next 或 n |
单步执行,不进入函数 |
next / n |
单步执行(进入函数) |
step 或 s |
单步执行,进入函数 |
step / s |
继续执行 |
continue 或 c |
继续执行直到下一个断点或程序结束 |
continue / c |
打印变量 |
print var 或 p var |
打印变量值 |
print var / p var |
查看调用栈 |
bt 或 thread backtrace |
查看当前调用栈 |
backtrace / bt |
查看源码 |
list 或 l |
查看当前代码 |
list / l |
退出调试 |
quit 或 q |
退出调试器 |
quit / q |
四、LLDB 的高级功能介绍
1. 对多线程的支持
LLDB 支持查看线程列表,切换线程,查看线程状态:
thread list thread select 2 thread info
GDB 也支持多线程,但 LLDB 对 macOS 和 ARM64 的线程调试更友好。
2. Watchpoint(监视点)
LLDB 支持对变量内存变化设置监视点:
watchpoint set variable myVar
适合调试内存相关错误。
3. 表达式求值和脚本
LLDB 支持用 Python 脚本扩展功能。
可以在调试时写 Python 脚本执行复杂操作。
4. 代码补全与命令历史
LLDB 支持 tab 补全和命令历史,比 GDB 交互体验更好。
五、macOS LLDB 与 GDB 对比总结
特性/维度 |
LLDB (macOS) |
GDB (macOS) |
---|---|---|
默认安装 |
macOS 自带,Xcode 自带 |
需要自己安装 |
支持架构 |
原生支持 ARM64 和 x86_64 |
主要支持 x86_64,ARM64 支持有限 |
调试符号支持 |
完美支持 Apple clang 生成的 DWARF 格式 |
对 Apple DWARF 支持不完全,常报错 |
交互体验 |
命令补全、脚本扩展、历史记录完善 |
较传统,交互性不如 LLDB |
多线程调试 |
优秀 |
支持,但不如 LLDB 友好 |
脚本支持 |
支持 Python |
有脚本支持,但相对较弱 |
适用场景 |
macOS 和 iOS 开发首选调试器 |
Linux 和跨平台项目常用 |
易用性 |
现代化,用户体验更好 |
历史久远,但命令更繁琐 |
六、简单 LLDB 调试流程示例
gcc -g -O0 gdb.c -o myprog # 编译带调试符号程序
lldb myprog # 启动 lldb 调试器(lldb) b main # 在 main 函数设置断点
(lldb) run # 运行程序
(lldb) n # 单步,不进入函数
(lldb) s # 单步,进入函数
(lldb) p var # 打印变量
(lldb) bt # 查看调用栈
(lldb) c # 继续运行至下一个断点b
(lldb) q # 退出(lldb) display x #变量的常显示
(lldb)until num #跳出循环至下一次有效代码行num
(lldb) expr sum = 10 # 修改变量值
(lldb) frame variable #查看当前函数的所有局部变量
七、总结
在 macOS 上调试,强烈推荐用 LLDB。
LLDB 对 macOS 和 Apple Silicon 有天然支持,调试体验比 GDB 好很多。
GDB 虽然经典且跨平台,但在 macOS 上使用常碰到架构兼容性和调试信息格式问题。
如果你熟悉 GDB 命令,LLDB 也能快速上手,命令基本兼容,还支持更多现代功能。