LLDB和GDB
-
GDB(GNU Debugger):
- GDB 是 GNU 项目的一部分,历史悠久,最早发布于 1986 年。它广泛支持多种操作系统和架构,特别是在 Linux 环境下。
- GDB 的设计初衷是为了支持 C 和 C++ 语言,但它也支持其他多种语言。
- GDB 的性能在许多情况下是可靠的,但在处理大型程序或复杂数据结构时,可能会显得稍慢。
- GDB 提供了丰富的功能,包括远程调试、条件断点、观察点等。
-
LLDB:
- LLDB 是 LLVM 项目的一部分,构建于 Clang 编译器的基础上。它相对较新,首次发布于 2009 年。
- LLDB 主要针对 macOS 和 iOS 开发,但也支持 Linux 和其他平台。
- LLDB 的设计目标是提供更高的性能和更好的用户体验,特别是在调试大型程序时。
- LLDB 通常在性能上表现更好,特别是在调试大型 C++ 程序时。
- LLDB 支持更现代的 C++ 特性,如模板和 STL(标准模板库)数据结构的调试。
- LLDB 也支持多线程调试,并且在处理线程时的用户体验更为友好。
LLDB命令
- GDB 和 LLDB 在命令和语法上有一些差异,尽管许多基本命令相似。例如:
- 设置断点:
break main
(GDB) vs.break main
(LLDB) - 继续执行:
continue
(GDB 和 LLDB 相同) - 查看变量:
print var
(GDB) vs.frame variable var
(LLDB,虽然print var
也可以使用)
- 设置断点:
命令 | 缩写 | 作用 |
breakpoint | b | 在指定位置设置断电 |
run | r | 运行程序到断点为止 |
step | s | 进入下一步的函数内部 |
backtrace | bt | 显示有效函数信息 |
frame | f | 显示堆栈内容 |
next | t | 运行到下一行 |
continue | c | 运行到下一个断点或者结束 |
p | 打印变量 | |
qiut | q | 退出 |
示例程序
// sum.cpp
#include <iostream>
int add(int a, int b) {
return a + b;
}
int main() {
int x = 5;
int y = 10;
int result = add(x, y);
// 故意制造一个错误:这里我们将 result 乘以一个错误的值
// 例如,使用一个未定义的变量 z
int z; // z 未初始化
std::cout << "The result is: " << result * z << std::endl; // 这里会导致未定义行为
return 0;
}
运行调试
编译命令要加上 -g 才能调试
g++ -g sum.cpp -o sum
启动lldb
lldb ./sum
在 main
函数的开始处设置一个断点,以便在程序执行到这里时暂停。
(lldb) breakpoint set --name main
运行到断点处
(lldb) run
如图,可以看到左侧的指针指到了main函数中的第一行,即下一行要执行的代码
(lldb) print x
(int) -268517296
这时候打印x,发现还没有被赋值
使用next 执行到函数入口,step进入
(lldb) step
查看有效函数,backtrace用不了则使用bt
(lldb) bt
接着使用next即可退出这个函数
观察result的状态
执行到错误代码,观察调用堆栈和变量,这里z被设置为1了