TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

455 lines
8.8 KiB

# 调试模式使用指南
## 📋 概述
`--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
希望这个指南能帮助您有效使用调试模式!