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

调试模式使用指南

📋 概述

--debug-info 参数用于启用调试模式,它会自动:

  1. 禁用优化-O0/Od
  2. 添加调试信息-g/Zi
  3. 生成符号文件.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: 可能的原因:

  1. 变量被优化掉了(即使使用 -O0
  2. 变量超出了作用域
  3. 调试信息不完整

解决方案:

# 使用更详细的调试信息
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:

  1. 添加日志输出
  2. 使用消息框显示变量值
  3. 使用 AddressSanitizer 检测错误
  4. 查看核心转储(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

💡 提示

  1. 始终在开发时使用 --debug-info

    • 更容易找到 bug
    • 更好的错误报告
    • 支持调试器
  2. 发布前移除 --debug-info

    • 更好的性能
    • 更小的文件
    • 更安全(不暴露符号)
  3. 结合使用多种调试工具

    • 调试器(GDB/LLDB/VS)
    • Sanitizer(AddressSanitizer 等)
    • 日志记录
    • Profiler

希望这个指南能帮助您有效使用调试模式!