调试(Debugging)是找出并修掉程序里的错误。这里按工具、技术、技巧和性能剖析四方面整理常用做法:
1. 调试工具
- 调试器(Debugger):调试器是用于检查和控制程序执行的工具。它允许开发者逐步执行代码、检查变量值、设置断点等。常见的调试器包括
gdb(用于 C/C++)、delve(用于 Go)、pdb(用于 Python)等。 - 日志记录(Logging):在代码中插入日志语句,记录程序运行时的状态和错误信息,用来回答"程序当时干了什么"。
2. 调试技术
- 断点(Breakpoints):断点是指在程序的某一行代码上设置的标记,当程序执行到这行代码时会暂停,允许开发者检查当前状态。
- 单步执行(Step Execution):单步执行是指逐行执行程序代码,观察每一行代码的执行效果。常见的操作有“单步进入(Step Into)”、“单步跳过(Step Over)”和“单步跳出(Step Out)”。
- 观察变量(Watch Variables):实时查看变量的值,跟踪程序中数据的变化。
- 调用栈(Call Stack):调用栈显示程序当前的执行路径,包括函数调用的顺序和层级关系,把错误定位到具体调用链靠它。
- 条件断点(Conditional Breakpoints):条件断点在满足特定条件时才会中断程序执行,适用于调试特定情况下的问题。
- 核心转储(Core Dumps):核心转储是程序崩溃时生成的内存快照,可以用来分析程序崩溃的原因。
3. 调试技巧
- 二分法调试:逐步缩小问题范围,快速定位问题所在。通过注释掉部分代码或使用日志,可以快速确定问题发生的区域。
- 边界测试:检查程序在处理边界条件(如最大值、最小值、空值等)时的表现,确保程序的鲁棒性。
- 单元测试(Unit Testing):编写单元测试可以在开发早期捕获错误,并保证代码在修改后的正确性。
4. 性能调试
- 性能剖析(Profiling):性能剖析工具(如
perf、gprof、pprof等)用于分析程序的运行时间、内存使用等性能指标,帮助找出性能瓶颈。 - 火焰图(Flame Graphs):火焰图是一种可视化工具,用于展示函数调用的时间分布,帮助识别性能热点。
5. 调试最佳实践
- 问题一出现就查:拖到后面查,那时代码改动更多,要对照的变量也更多。
- 保持简洁:调试时保持代码简洁,把关键的调试信息写进注释。
- 记录和分析:把每一步的观察结果记下来,形成日后可查的处理过程文档。