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.
8.8 KiB
8.8 KiB
调试模式使用指南
📋 概述
--debug-info 参数用于启用调试模式,它会自动:
- 禁用优化(
-O0或/Od) - 添加调试信息(
-g或/Zi) - 生成符号文件(
.pdb文件,Windows)
这使得您可以使用调试器(如 GDB、LLDB、Visual Studio)来调试编译后的程序。
🚀 快速开始
Windows (MSVC)
# 启用调试模式
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)
# 启用调试模式
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. 基本调试
# 编译带调试信息的版本
php bin/compiler.php debug-test.php --debug-info --no-console
# 在 Visual Studio 中调试
# - 打开 debug-test.exe
# - 设置断点
# - 按 F5 运行
# - 查看变量值、调用堆栈
2. 结合 AddressSanitizer
# 同时启用调试信息和 AddressSanitizer
php bin/compiler.php asan-test.php --debug-info --sanitize=address --no-console
# 这样可以:
# - 看到源代码行号
# - 检测内存错误
# - 获得详细的错误报告
3. GDB 调试 (Linux)
# 编译
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)
# 编译
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) break main if x > 10
# LLDB
(lldb) breakpoint set --name main --condition 'x > 10'
2. 观察点(Watchpoint)
# 当变量改变时中断
(gdb) watch my_variable
(gdb) continue
3. 检查内存
# GDB
(gdb) x/10x &array # 查看数组的前 10 个元素
(gdb) p *ptr@10 # 查看指针指向的 10 个元素
# LLDB
(lldb) memory read --format x --count 10 &array
4. 多线程调试
# 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++ 扩展
优化选项:
# 基本调试
-g
# GDB 专用
-ggdb
# 更多详细信息
-g3
# 仅调试宏
-ggdb3
macOS (Clang)
调试信息:
- 默认使用 DWARF 格式
- 嵌入到可执行文件中
调试工具:
- LLDB(默认)
- Xcode
- Visual Studio Code + C++ 扩展
特殊选项:
# 生成 dSYM 文件(分离调试信息)
-g -Wl,-S
# 保留所有符号
-g -fno-eliminate-unused-debug-types
🐛 常见问题
Q: 为什么调试模式下程序运行很慢?
A: 因为禁用了所有优化(-O0)。这是正常的,调试模式的目标是便于调试,而不是性能。
解决方案:
- 只在调试时使用
--debug-info - 发布时使用
-O2或-O3
Q: 调试器看不到某些变量?
A: 可能的原因:
- 变量被优化掉了(即使使用
-O0) - 变量超出了作用域
- 调试信息不完整
解决方案:
# 使用更详细的调试信息
php bin/compiler.php app.php --debug-info
# 或者在 GCC/Clang 上
# 手动添加 -g3
Q: 如何调试 Release 版本?
A: 不推荐,但可以:
# 保留调试信息但启用优化
php bin/compiler.php app.php -O2 --debug-info
注意:优化可能会使调试变得困难,因为代码可能被重排或内联。
Q: PDB 文件太大怎么办?
A:
# 使用增量链接
/link /INCREMENTAL
# 或使用 FASTLINK
/link /DEBUG:FASTLINK
Q: 如何在没有调试器的情况下调试?
A:
- 添加日志输出
- 使用消息框显示变量值
- 使用 AddressSanitizer 检测错误
- 查看核心转储(core dump)
🎯 最佳实践
1. 开发工作流
# 日常开发
php bin/compiler.php app.php --debug-info
# 运行测试
./app
# 调试问题
gdb ./app
# 准备发布
php bin/compiler.php app.php -O2
2. 持续集成
# .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:
# 保留 PDB 文件
Copy-Item app.pdb symbols/
# 发布时剥离符号
# PDB 文件不需要分发给用户
Linux:
# 分离调试信息
objcopy --only-keep-debug app app.debug
strip app
# 使用时
gdb -s app.debug ./app
📚 相关资源
🔗 编译器命令参考
# 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
💡 提示
-
始终在开发时使用
--debug-info- 更容易找到 bug
- 更好的错误报告
- 支持调试器
-
发布前移除
--debug-info- 更好的性能
- 更小的文件
- 更安全(不暴露符号)
-
结合使用多种调试工具
- 调试器(GDB/LLDB/VS)
- Sanitizer(AddressSanitizer 等)
- 日志记录
- Profiler
希望这个指南能帮助您有效使用调试模式!