C语言高效调试
特此说明: 内容主要参考魏永明老师老师的课程 C 语言最佳实践高阶篇之高效调试,也可以看下面我整理的笔记。建议初级C程序员多看,干货多水分少,质量很高。
高效调试的基本原则
- 多读代码、读懂代码,在头脑中形成代码执行路径
- 不要慌,不要怀疑一切,尤其不要轻易怀疑编译工具链
- 快速找到第一现场,理清现象和缺陷的内在关联
- 复原现场,形成完整的证据链
- 知其然,更要知其所以然
- 避免使用低效调试手段
C 程序常见错误分类
编译、链接错误(5%)
- 编译错误
- 始终解决第一个错误
- 正确理解编译器给出的错误描述
- 链接错误:未找到某某符号
- 正确的函数库(包括版本)和库搜索路径
- 静态链接时,根据函数库依赖关系,调整函数库顺序
算法或逻辑错误(20%)
- 正确理解标准库及第三方函数库的接口语义
- 读懂代码,尤其代码产生的效果
- 单元测试
内存使用错误(70%)
- 静态数据使用错误
- 方式:越界访问
- 影响:导致数据被意外篡改导致逻辑错误,严重使程序崩溃
- 堆使用错误
- 越界访问
- 方式:使用无效地址(空指针、野指针或者已释放的指针)、内存泄露(忘记释放)、两次释放、释放非分配地址
- 影响:导致数据被意外篡改导致逻辑错误,严重使程序崩溃
- 栈使用错误
- 方式:越界访问、栈溢出
- 影响:数据被意外篡改导致逻辑错误,导致程序跑飞,程序崩溃
疑难杂症(5%)
- 命名污染,导致调用错误的函数或者使用错误的全局变量
- 整数溢出:逻辑错误(死循环)
- 异步数据访问:Unix 系统中的信号处理;多线程程序中出现竞态(race-condition)
善用调试工具
- 调试器:程序挂在哪儿了?
- efence:程序是否有堆使用错误?
- valgrind:是否存在内存泄露?
- 打桩