第 7 章:调试、测试、性能分析
第 71--80 节 C 的调试工具强大但依赖手动操作。Auto 旨在在错误发生之前就阻止它们。
调试是 C 和 Auto 差异最显著的地方。C 程序可能有只在特定条件下才出现的 微妙内存错误。gdb 和 valgrind 等工具之所以存在,正是因为 C 缺乏安全 保证使得它们成为必需品。
Auto 在语言层面阻止了许多这类错误。当错误确实发生时,Auto 的测试框架 和断言能帮助尽早发现。本章涵盖你应该了解的 C 工具以及 Auto 的内置替代 方案。
71. 使用 GDB 调试
GDB(GNU 调试器)是标准的 C 调试器。它可以让你:
- 设置断点在某一行暂停执行
- 逐行单步执行代码
- 检查变量和内存
- 查看调用栈
bash
$ gcc -g program.c -o program # -g 添加调试符号
$ gdb ./program
(gdb) break main
(gdb) run
(gdb) next
(gdb) print x
(gdb) backtraceGDB 功能强大但学习曲线陡峭。大多数开发者通过 VS Code 的调试适配器 或 TUI 界面来使用它。
Auto 目前还没有专用调试器,但由于 Auto 转译为 C,你可以在生成的 C 代码上使用 GDB。映射关系很直接,因为 Auto 构造直接对应 C 等价物。
72. Valgrind 内存检查
Valgrind 检测编译器和运行时检查遗漏的内存错误:
bash
$ valgrind --leak-check=full ./program
==1234== Invalid read of size 4
==1234== at 0x400544: main (program.c:12)
==1234== Address 0x5205054 is 0 bytes after a block of size 4 alloc'dValgrind 能捕获:
- 释放后使用
- 缓冲区溢出(读和写)
- 内存泄漏
- 未初始化内存读取
运行 Valgrind 很慢 —— 程序会慢 10-50 倍。它通常在 CI 流水线中或 追踪特定错误时使用。
Auto 在大多数情况下使 Valgrind 变得不必要,因为语言在编译时阻止了 这些错误。边界检查、所有权追踪和可选类型消除了 Valgrind 检测的整类 内存错误。
73. 断言
断言是验证条件为真的运行时检查。如果失败,程序会中止并显示消息。
C 断言:
c
#include <assert.h>
assert(x > 0); /* 简单断言 */
assert(ptr != NULL && "ptr must not be null"); /* 带消息 */Auto 断言:
auto
assert(x > 0, "x 必须为正数")
assert(ptr != nil, "ptr 不能为 null")Auto 的 assert 按惯例包含消息参数,比 C 的默认断言输出更具信息量。 转译器将其映射为带有字符串化条件的 C assert()。