|
|
# 调试模式使用指南
|
|
|
|
|
|
## 📋 概述
|
|
|
|
|
|
`--debug-info` 参数用于启用调试模式,它会自动:
|
|
|
1. **禁用优化**(`-O0` 或 `/Od`)
|
|
|
2. **添加调试信息**(`-g` 或 `/Zi`)
|
|
|
3. **生成符号文件**(`.pdb` 文件,Windows)
|
|
|
|
|
|
这使得您可以使用调试器(如 GDB、LLDB、Visual Studio)来调试编译后的程序。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🚀 快速开始
|
|
|
|
|
|
### Windows (MSVC)
|
|
|
|
|
|
```powershell
|
|
|
# 启用调试模式
|
|
|
php bin/compiler.php your-app.php --debug-info
|
|
|
|
|
|
# 结合其他选项
|
|
|
php bin/compiler.php your-app.php --debug-info --no-console
|
|
|
|
|
|
# 运行程序
|
|
|
.\your-app.exe
|
|
|
|
|
|
# 使用 Visual Studio 调试
|
|
|
# 1. 打开 your-app.exe
|
|
|
# 2. 按 F5 启动调试
|
|
|
# 3. 设置断点,查看变量
|
|
|
```
|
|
|
|
|
|
### Linux/macOS (GCC/Clang)
|
|
|
|
|
|
```bash
|
|
|
# 启用调试模式
|
|
|
php bin/compiler.php your-app.php --debug-info
|
|
|
|
|
|
# 结合其他选项
|
|
|
php bin/compiler.php your-app.php --debug-info --sanitize=address
|
|
|
|
|
|
# 运行程序
|
|
|
./your-app
|
|
|
|
|
|
# 使用 GDB 调试
|
|
|
gdb ./your-app
|
|
|
(gdb) break main
|
|
|
(gdb) run
|
|
|
(gdb) next
|
|
|
(gdb) print variable_name
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🔍 调试模式 vs 发布模式
|
|
|
|
|
|
| 特性 | 调试模式 (`--debug-info`) | 发布模式 (默认) |
|
|
|
|------|--------------------------|----------------|
|
|
|
| 优化级别 | `-O0` / `/Od` (禁用) | `-O2` / `/O2` (最大速度) |
|
|
|
| 调试信息 | ✅ 生成 (`-g` / `/Zi`) | ❌ 不生成 |
|
|
|
| 符号文件 | ✅ 生成 (`.pdb`) | ❌ 不生成 |
|
|
|
| 执行速度 | 较慢 | 快 |
|
|
|
| 文件大小 | 较大 | 较小 |
|
|
|
| 适用场景 | 开发、调试 | 生产环境 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 💡 使用示例
|
|
|
|
|
|
### 1. 基本调试
|
|
|
|
|
|
```powershell
|
|
|
# 编译带调试信息的版本
|
|
|
php bin/compiler.php debug-test.php --debug-info --no-console
|
|
|
|
|
|
# 在 Visual Studio 中调试
|
|
|
# - 打开 debug-test.exe
|
|
|
# - 设置断点
|
|
|
# - 按 F5 运行
|
|
|
# - 查看变量值、调用堆栈
|
|
|
```
|
|
|
|
|
|
### 2. 结合 AddressSanitizer
|
|
|
|
|
|
```powershell
|
|
|
# 同时启用调试信息和 AddressSanitizer
|
|
|
php bin/compiler.php asan-test.php --debug-info --sanitize=address --no-console
|
|
|
|
|
|
# 这样可以:
|
|
|
# - 看到源代码行号
|
|
|
# - 检测内存错误
|
|
|
# - 获得详细的错误报告
|
|
|
```
|
|
|
|
|
|
### 3. GDB 调试 (Linux)
|
|
|
|
|
|
```bash
|
|
|
# 编译
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# 启动 GDB
|
|
|
gdb ./app
|
|
|
|
|
|
# GDB 常用命令
|
|
|
(gdb) break main # 在 main 函数设置断点
|
|
|
(gdb) break filename:10 # 在第 10 行设置断点
|
|
|
(gdb) run # 运行程序
|
|
|
(gdb) next # 执行下一行
|
|
|
(gdb) step # 进入函数
|
|
|
(gdb) print var # 打印变量值
|
|
|
(gdb) backtrace # 显示调用堆栈
|
|
|
(gdb) continue # 继续执行
|
|
|
(gdb) quit # 退出
|
|
|
```
|
|
|
|
|
|
### 4. LLDB 调试 (macOS)
|
|
|
|
|
|
```bash
|
|
|
# 编译
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# 启动 LLDB
|
|
|
lldb ./app
|
|
|
|
|
|
# LLDB 常用命令
|
|
|
(lldb) breakpoint set --name main
|
|
|
(lldb) run
|
|
|
(lldb) next
|
|
|
(lldb) step
|
|
|
(lldb) frame variable
|
|
|
(lldb) thread backtrace
|
|
|
(lldb) continue
|
|
|
(lldb) quit
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🛠️ 高级技巧
|
|
|
|
|
|
### 1. 条件断点
|
|
|
|
|
|
```gdb
|
|
|
# GDB
|
|
|
(gdb) break main if x > 10
|
|
|
|
|
|
# LLDB
|
|
|
(lldb) breakpoint set --name main --condition 'x > 10'
|
|
|
```
|
|
|
|
|
|
### 2. 观察点(Watchpoint)
|
|
|
|
|
|
```gdb
|
|
|
# 当变量改变时中断
|
|
|
(gdb) watch my_variable
|
|
|
(gdb) continue
|
|
|
```
|
|
|
|
|
|
### 3. 检查内存
|
|
|
|
|
|
```gdb
|
|
|
# GDB
|
|
|
(gdb) x/10x &array # 查看数组的前 10 个元素
|
|
|
(gdb) p *ptr@10 # 查看指针指向的 10 个元素
|
|
|
|
|
|
# LLDB
|
|
|
(lldb) memory read --format x --count 10 &array
|
|
|
```
|
|
|
|
|
|
### 4. 多线程调试
|
|
|
|
|
|
```gdb
|
|
|
# GDB
|
|
|
(gdb) info threads # 查看所有线程
|
|
|
(gdb) thread 2 # 切换到线程 2
|
|
|
(gdb) thread apply all bt # 所有线程的堆栈
|
|
|
|
|
|
# LLDB
|
|
|
(lldb) thread list
|
|
|
(lldb) thread select 2
|
|
|
(lldb) thread backtrace all
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 📊 性能对比
|
|
|
|
|
|
### 编译时间
|
|
|
|
|
|
| 模式 | 相对时间 |
|
|
|
|------|---------|
|
|
|
| 发布模式 (-O2) | 100% |
|
|
|
| 调试模式 (-O0 -g) | 80% (更快) |
|
|
|
|
|
|
### 运行时性能
|
|
|
|
|
|
| 模式 | 相对速度 | 内存使用 |
|
|
|
|------|---------|---------|
|
|
|
| 发布模式 (-O2) | 100% | 100% |
|
|
|
| 调试模式 (-O0 -g) | 30-50% | 120-150% |
|
|
|
|
|
|
### 文件大小
|
|
|
|
|
|
| 模式 | 可执行文件 | 符号文件 |
|
|
|
|------|-----------|---------|
|
|
|
| 发布模式 | 小 | 无 |
|
|
|
| 调试模式 | 大 | .pdb (Windows) / 嵌入 (Unix) |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🔧 平台特定说明
|
|
|
|
|
|
### Windows (MSVC)
|
|
|
|
|
|
**生成的文件:**
|
|
|
- `app.exe` - 可执行文件
|
|
|
- `app.pdb` - 程序数据库文件(包含调试信息)
|
|
|
|
|
|
**调试工具:**
|
|
|
- Visual Studio 2022(推荐)
|
|
|
- WinDbg
|
|
|
- Visual Studio Code + C++ 扩展
|
|
|
|
|
|
**注意事项:**
|
|
|
- PDB 文件必须与 EXE 在同一目录
|
|
|
- 不要删除 PDB 文件,否则无法调试
|
|
|
- 可以使用 `/DEBUG:FASTLINK` 加快链接速度
|
|
|
|
|
|
### Linux (GCC)
|
|
|
|
|
|
**调试信息:**
|
|
|
- 默认嵌入到可执行文件中
|
|
|
- 也可以使用 `-ggdb` 生成 GDB 专用信息
|
|
|
|
|
|
**调试工具:**
|
|
|
- GDB
|
|
|
- DDD (GDB 图形界面)
|
|
|
- Visual Studio Code + C++ 扩展
|
|
|
|
|
|
**优化选项:**
|
|
|
```bash
|
|
|
# 基本调试
|
|
|
-g
|
|
|
|
|
|
# GDB 专用
|
|
|
-ggdb
|
|
|
|
|
|
# 更多详细信息
|
|
|
-g3
|
|
|
|
|
|
# 仅调试宏
|
|
|
-ggdb3
|
|
|
```
|
|
|
|
|
|
### macOS (Clang)
|
|
|
|
|
|
**调试信息:**
|
|
|
- 默认使用 DWARF 格式
|
|
|
- 嵌入到可执行文件中
|
|
|
|
|
|
**调试工具:**
|
|
|
- LLDB(默认)
|
|
|
- Xcode
|
|
|
- Visual Studio Code + C++ 扩展
|
|
|
|
|
|
**特殊选项:**
|
|
|
```bash
|
|
|
# 生成 dSYM 文件(分离调试信息)
|
|
|
-g -Wl,-S
|
|
|
|
|
|
# 保留所有符号
|
|
|
-g -fno-eliminate-unused-debug-types
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🐛 常见问题
|
|
|
|
|
|
### Q: 为什么调试模式下程序运行很慢?
|
|
|
|
|
|
A: 因为禁用了所有优化(`-O0`)。这是正常的,调试模式的目标是便于调试,而不是性能。
|
|
|
|
|
|
**解决方案:**
|
|
|
- 只在调试时使用 `--debug-info`
|
|
|
- 发布时使用 `-O2` 或 `-O3`
|
|
|
|
|
|
### Q: 调试器看不到某些变量?
|
|
|
|
|
|
A: 可能的原因:
|
|
|
1. 变量被优化掉了(即使使用 `-O0`)
|
|
|
2. 变量超出了作用域
|
|
|
3. 调试信息不完整
|
|
|
|
|
|
**解决方案:**
|
|
|
```bash
|
|
|
# 使用更详细的调试信息
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# 或者在 GCC/Clang 上
|
|
|
# 手动添加 -g3
|
|
|
```
|
|
|
|
|
|
### Q: 如何调试 Release 版本?
|
|
|
|
|
|
A: 不推荐,但可以:
|
|
|
```bash
|
|
|
# 保留调试信息但启用优化
|
|
|
php bin/compiler.php app.php -O2 --debug-info
|
|
|
```
|
|
|
|
|
|
注意:优化可能会使调试变得困难,因为代码可能被重排或内联。
|
|
|
|
|
|
### Q: PDB 文件太大怎么办?
|
|
|
|
|
|
A:
|
|
|
```powershell
|
|
|
# 使用增量链接
|
|
|
/link /INCREMENTAL
|
|
|
|
|
|
# 或使用 FASTLINK
|
|
|
/link /DEBUG:FASTLINK
|
|
|
```
|
|
|
|
|
|
### Q: 如何在没有调试器的情况下调试?
|
|
|
|
|
|
A:
|
|
|
1. 添加日志输出
|
|
|
2. 使用消息框显示变量值
|
|
|
3. 使用 AddressSanitizer 检测错误
|
|
|
4. 查看核心转储(core dump)
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🎯 最佳实践
|
|
|
|
|
|
### 1. 开发工作流
|
|
|
|
|
|
```bash
|
|
|
# 日常开发
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# 运行测试
|
|
|
./app
|
|
|
|
|
|
# 调试问题
|
|
|
gdb ./app
|
|
|
|
|
|
# 准备发布
|
|
|
php bin/compiler.php app.php -O2
|
|
|
```
|
|
|
|
|
|
### 2. 持续集成
|
|
|
|
|
|
```yaml
|
|
|
# .github/workflows/test.yml
|
|
|
- name: Debug Build
|
|
|
run: php bin/compiler.php tests/*.php --debug-info
|
|
|
|
|
|
- name: Run Tests with GDB
|
|
|
run: |
|
|
|
gdb -batch -ex "run" -ex "bt" ./test_app
|
|
|
|
|
|
- name: Release Build
|
|
|
run: php bin/compiler.php src/*.php -O2
|
|
|
```
|
|
|
|
|
|
### 3. 调试检查清单
|
|
|
|
|
|
遇到问题时:
|
|
|
- [ ] 是否使用 `--debug-info` 编译?
|
|
|
- [ ] 是否设置了断点?
|
|
|
- [ ] 是否查看了调用堆栈?
|
|
|
- [ ] 是否检查了变量值?
|
|
|
- [ ] 是否使用了 AddressSanitizer?
|
|
|
- [ ] 是否查看了日志文件?
|
|
|
|
|
|
### 4. 符号文件管理
|
|
|
|
|
|
**Windows:**
|
|
|
```powershell
|
|
|
# 保留 PDB 文件
|
|
|
Copy-Item app.pdb symbols/
|
|
|
|
|
|
# 发布时剥离符号
|
|
|
# PDB 文件不需要分发给用户
|
|
|
```
|
|
|
|
|
|
**Linux:**
|
|
|
```bash
|
|
|
# 分离调试信息
|
|
|
objcopy --only-keep-debug app app.debug
|
|
|
strip app
|
|
|
|
|
|
# 使用时
|
|
|
gdb -s app.debug ./app
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 📚 相关资源
|
|
|
|
|
|
- [GDB 用户手册](https://sourceware.org/gdb/current/onlinedocs/gdb/)
|
|
|
- [LLDB 教程](https://lldb.llvm.org/use/tutorial.html)
|
|
|
- [Visual Studio 调试](https://docs.microsoft.com/visualstudio/debugger/)
|
|
|
- [MSVC 调试选项](https://docs.microsoft.com/cpp/build/reference/z7-zi-ld-debug-information-format)
|
|
|
- [GCC 调试选项](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html)
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🔗 编译器命令参考
|
|
|
|
|
|
```powershell
|
|
|
# Windows - 基本调试
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# Windows - 调试 + GUI
|
|
|
php bin/compiler.php app.php --debug-info --no-console
|
|
|
|
|
|
# Windows - 调试 + ASan
|
|
|
php bin/compiler.php app.php --debug-info --sanitize=address
|
|
|
|
|
|
# Linux/macOS - 基本调试
|
|
|
php bin/compiler.php app.php --debug-info
|
|
|
|
|
|
# Linux/macOS - 调试 + 多个 sanitizer
|
|
|
php bin/compiler.php app.php --debug-info --sanitize=address,undefined
|
|
|
|
|
|
# 自定义优化级别(不使用调试模式)
|
|
|
php bin/compiler.php app.php -O2
|
|
|
|
|
|
# 完全禁用优化(不生成调试信息)
|
|
|
php bin/compiler.php app.php -O0
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 💡 提示
|
|
|
|
|
|
1. **始终在开发时使用 `--debug-info`**
|
|
|
- 更容易找到 bug
|
|
|
- 更好的错误报告
|
|
|
- 支持调试器
|
|
|
|
|
|
2. **发布前移除 `--debug-info`**
|
|
|
- 更好的性能
|
|
|
- 更小的文件
|
|
|
- 更安全(不暴露符号)
|
|
|
|
|
|
3. **结合使用多种调试工具**
|
|
|
- 调试器(GDB/LLDB/VS)
|
|
|
- Sanitizer(AddressSanitizer 等)
|
|
|
- 日志记录
|
|
|
- Profiler
|
|
|
|
|
|
希望这个指南能帮助您有效使用调试模式!
|
|
|
|