调试(英語:Debugging)是发现和减少计算机程序软件或软体系统中程序错误的过程[1]

「调试」的各地常用名稱
中國大陸调试
臺灣除錯、偵錯

调试是软件开发过程中的重要环节。调试技术包括交互式调试、日志文件分析、静态分析核心转储分析以及性能分析等。许多编程语言和集成开发环境提供了专门的调试工具[2]

词源与历史

编辑

「调试」(debugging)一词源自计算机科学早期的著名典故。1947年,葛丽丝·霍普(Grace Hopper)在哈佛马克二号计算机的继电器中发现了一只飞蛾,导致计算机故障。她将这只飞蛾贴在日志中,并注明「First actual case of bug being found」[3]。「bug」一词此前已在工程领域用于指代缺陷,但霍普的发现使其在计算机领域广泛流行。

早期的调试手段十分原始。程序员通过机器语言、拨动开关和检查内存指示灯来排查问题。1960年代后,汇编语言高级语言的出现催生了早期的调试工具,如FORTAN的流程跟踪。1970年代,Unix操作系统引入了adbsdb等命令行调试器。1990年代以来,随着图形用户界面集成开发环境的普及,调试工具逐步集成到IDE中,支持断点设置、变量监视和单步执行等功能[1]

程序错误的类型

编辑

程序错误(bug)可按其性质和影响分类[2]

  • 语法错误(Syntax Error):违反编程语言的语法规则,通常在编译阶段被检测到。
  • 运行时错误(Runtime Error):程序在执行过程中出现的错误,如空指针解引用、除零错误、段错误
  • 逻辑错误(Logic Error):程序能够运行但产生错误结果,是最难排查的类型。
  • 内存错误:包括内存泄漏缓冲区溢出悬空指针释放后使用(use-after-free)。
  • 并发错误:在多线程或多进程环境中出现,包括竞态条件死锁活锁
  • 语义错误:代码在语法上正确,但未能实现预期的语义含义。

调试技术

编辑

调试技术涵盖从手动检查到自动化分析的多种方法[1]

  • 打印调试(Print Debugging):在代码中插入输出语句(如printf、console.log)来跟踪变量值和程序流程。是最简单也是最广泛使用的调试手段。
  • 交互式调试(Interactive Debugging):使用调试器设置断点(breakpoint)、监视点(watchpoint),逐行或逐指令执行代码,检查变量和调用栈。主流IDE内置的调试器均支持此功能。
  • 静态分析(Static Analysis):在不运行代码的情况下通过lint类工具或编译器的警告信息检测潜在问题。
  • 核心转储分析(Core Dump Analysis):程序崩溃后分析保存的内存映像,定位崩溃位置和原因。
  • 二分查找法(Binary Search / Delta Debugging):通过反复将可疑代码范围减半来缩小问题定位区域。
  • 断言(Assertion):在代码中插入断言语句,在运行时检查条件是否满足,快速发现逻辑错误。
  • 橡皮鸭调试法(Rubber Duck Debugging):向橡皮鸭或其他听众逐行解释代码,在叙述过程中发现自己的逻辑错误。
  • 远程调试(Remote Debugging):调试在另一台机器或嵌入式设备上运行的程序,常用于嵌入式系统和服务器端开发。
  • 逆向执行调试(Reverse / Time Travel Debugging):记录程序执行轨迹,允许开发者在时间上回退以观察变量变化过程。

调试工具

编辑

常用的调试工具包括[1][2]

参见

编辑

参考文献

编辑
  1. ^ 1.0 1.1 1.2 1.3 Zeller, A. Why Programs Fail: A Guide to Systematic Debugging 2nd. Morgan Kaufmann. 2009. ISBN 978-0-123-74515-6. 
  2. ^ 2.0 2.1 2.2 McConnell, S. Code Complete 2nd. Microsoft Press. 2004. ISBN 978-0-735-61967-8. 
  3. ^ The First Computer Bug. Naval History and Heritage Command. [2026-05-13]. 

📚 Artikel Terkait di Wikipedia

排错

态及近期的变更历史,并通过排除法将问题一步步简化。 排错涵盖从机械故障诊断到软件缺陷修复的广泛范围。在软件工程领域,排错的特化形式称为调试(debugging),即查找、分析和修复程序错误的过程。对于软件排错,常用的手段包括交互式调试、控制流分析、日志文件分析、应用或系统级监控、内存转储分析和性能

C预处理器

擴展巨集与预处理指令(directive)处理。 用于包含另一个文件: #include <stdio.h> int main(void) { printf("Hello, world!\n"); return 0; } if-else指令包括#if, #ifdef, #ifndef, #else,

記憶體區段錯誤

并且使用可能导致不用堆栈的尾调优化。其他优化可能包括将递归转换为迭代,鉴于示例函数的结构,程序将永远运行下去,同时大概率不会导致堆栈溢出。 Debugging Segmentation Faults and Pointer Problems - Cprogramming.com. www.cprogramming

Python

changing behavior in existing code is desired. It includes tools for debugging and testing: simple mock/record and a complete capture/replay framework

CPUID

%rdi movl %eax,%esi xorl %eax,%eax call printf leaq s2(%rip),%rdi movq %rsp,%rsi xorl %eax,%eax call printf movq %rbp,%rsp popq %rbp // ret movl $1,%eax