软件工程/工具/调试器简介
调试器或调试工具是一种用于测试和调试其他程序(“目标”程序)的计算机程序。要检查的代码也可能在指令集模拟器(ISS)上运行,这种技术在其在遇到特定条件时停止的能力方面具有强大的功能,但通常比直接在适当的(或相同的)处理器上执行代码速度慢一些。 一些调试器提供两种操作模式 - 全模拟或部分模拟,以限制这种影响。
当程序由于编程错误而无法正常继续时,就会发生“崩溃”。例如,程序可能尝试使用当前版本的 CPU 上不可用的指令,或尝试访问不可用或受保护的内存。当程序“崩溃”或达到预设条件时,调试器通常会显示原始代码中的位置,如果它是源代码级调试器或符号调试器,现在通常在集成开发环境中看到。 如果它是低级调试器或机器语言调试器,它将显示反汇编中的行(除非它还具有在线访问原始源代码的能力,并且可以显示来自汇编或编译的代码的相应部分)。
通常,调试器还提供更复杂的功能,例如逐行运行程序(单步执行或程序动画),通过断点在某个事件或指定指令处停止(中断)(暂停程序以检查当前状态),并跟踪某些变量的值。 一些调试器能够在程序运行时修改程序的状态,而不仅仅是观察它。 也许还可以继续在程序中的不同位置执行以绕过崩溃或逻辑错误。
一个好的调试器的重要性不可言喻。实际上,对于给定的语言和平台,这种工具的存在和质量往往是决定其使用的因素,即使另一种语言/平台更适合该任务。 [需要引用]。 有人说,在习惯了使用调试器后,没有调试器会“让你感觉像一个在黑暗的房间里寻找一只不存在的黑猫的盲人”。[1] 然而,由于调试器必然会对软件程序的内部计时产生影响,因此软件在调试器下运行的方式(通常确实如此)与正常运行的方式不同。因此,即使使用了一个好的调试工具,也很难追踪复杂的多线程或分布式系统中的运行时问题。
使调试器对消除错误有用的相同功能使其可以作为软件破解工具来逃避复制保护、数字版权管理和其他软件保护功能。它通常也使其用作通用测试验证工具测试覆盖率和性能分析器,尤其是在显示指令路径长度的情况下。
大多数当前的主流调试引擎,如 gdb 和 dbx,都提供基于控制台的命令行界面。调试器前端是对调试器引擎的流行扩展,它提供了 IDE 集成、程序动画和可视化功能。 一些早期的大型机调试器,如 IBM OLIVER(CICS 交互式测试/调试)和 SIMON(批处理交互式测试/调试),早在 1970 年代就为 IBM System/360 及更高版本的操作系统提供了相同的功能。
一些调试器针对单一特定语言运行,而另一些则可以透明地处理多种语言。例如,如果主要目标程序是用 COBOL 编写的,但调用了汇编子例程以及 PL/1 子例程,则调试器可以动态切换模式以适应语言的更改。
一些调试器还包含内存保护以避免存储冲突,例如缓冲区溢出。这在事务处理环境中可能非常重要,在事务处理环境中,内存是从任务到任务的基础上从内存“池”中动态分配的。
大多数现代微处理器在其 CPU 设计中至少具有以下一项功能,以使调试更容易
- 对程序进行单步执行的硬件支持,例如陷阱标志。
- 满足 Popek 和 Goldberg 虚拟化要求的指令集使编写在与正在调试的软件相同的 CPU 上运行的调试器软件变得更容易;这样的 CPU 可以全速执行被测程序的内部循环,并且仍然在调试器的控制之下。
- 系统内编程允许外部硬件调试器重新编程被测系统(例如,添加或删除指令断点)。许多具有此类 ISP 支持的系统也具有其他硬件调试支持。
- 对代码和数据断点的硬件支持,例如地址比较器和数据值比较器,或者在需要更多工作的情况下,页面错误硬件。
- 对硬件调试接口的 JTAG 访问,例如 ARM 架构处理器上的那些接口,或使用 Nexus 命令集。嵌入式系统中使用的处理器通常具有广泛的 JTAG 调试支持。
- 只有 6 个引脚的微控制器需要使用 JTAG 的低引脚数替代品,例如 Atmel AVR 上的 BDM、Spy-Bi-Wire 或 DebugWire。例如,DebugWire 在 RESET 引脚上使用双向信号。
- AppPuncher 调试器 - 用于调试富互联网应用程序
- AQtime
- CA/EZTEST - 是一个 CICS 交互式测试/调试软件包
- CharmDebug - Charm++ 的调试器
- CodeView
- DBG - 一个 PHP 调试器和分析器
- dbx
- DDD(数据显示调试器)
- 分布式调试工具(Allinea DDT)
- DDTLite - 适用于 Visual Studio 2008 的 Allinea DDTLite
- DEBUG - DOS 和 Microsoft Windows 的内置调试器
- MySQL 调试器
- Opera Dragonfly
- 动态调试技术 (DDT) 及其八进制对应物八进制调试技术
- Eclipse
- 适用于 Eclipse 的嵌入式系统调试插件
- FusionDebug
- gDEBugger OpenGL、OpenGL ES 和 OpenCL 调试器和分析器。 适用于 Windows、Linux、Mac OS X 和 iPhone
- GNU 调试器 (GDB)、GNU Binutils
- 英特尔调试器 (IDB)
- Insight
- Parasoft Insure++
- iSYSTEM - 嵌入式系统的在线调试器
- 交互式反汇编器 (IDA Pro)
- Java 平台调试器体系结构
- Jinx - 用于 heisenbugs 的全系统调试器。 它作为设备驱动程序透明地工作。
- JSwat - 开源 Java 调试器
- LLDB
- MacsBug
- Nemiver - GNOME 桌面环境的图形 C/C++ 调试器
- OLIVER(CICS 交互式测试/调试) - 一个配备 GUI 的指令集模拟器(ISS)
- OllyDbg
- FlexTracer - SQL 语句的共享软件调试器
- Omniscient Debugger - 用于 Java 的前向和后向调试器
- pydbg
- IBM Rational Purify
- RealView Debugger - ARM 为其生产和设计的商业调试器
- sdb
- SIMMON(模拟监视器)
- SIMON(批处理交互式测试/调试)—— 一款用于批处理的配备了 GUI 的指令集模拟器
- SoftICE
- TimeMachine——由 Green Hills Software 设计的向前和向后调试器
- TotalView
- TRACE32——用于嵌入式系统的在线调试器
- Turbo Debugger
- Ups——C、Fortran 源代码级调试器
- Valgrind
- VB Watch Debugger——Visual Basic 6.0 的调试器
- Microsoft Visual Studio 调试器
- WinDbg
- WonderLeak - 高性能 Windows 堆和句柄分配分析器。
- Xdebug——PHP 调试器和分析器
一些功能最强大和最流行的调试器只实现了简单的命令行界面 (CLI),这通常是为了最大程度地提高可移植性和最小化资源消耗。虽然通过图形用户界面 (GUI) 进行调试可以被认为更容易、更高效。这就是 GUI 调试器前端的原因,它允许用户通过图形用户界面监控和控制从属的仅 CLI 调试器。一些 GUI 调试器前端设计为兼容各种仅 CLI 调试器,而另一些则针对一个特定的调试器。
- 许多集成开发环境都带有集成调试器(或标准调试器的前端)。
- 许多 Eclipse 透视图,例如 Java 开发工具 (JDT) [1],提供了一个调试器前端。
- DDD 是 GNU 项目的标准前端。它是一个复杂的工具,可以与大多数常见的调试器(GDB、jdb、Python 调试器、Perl 调试器、Tcl 等)原生或通过一些外部程序(用于 PHP)一起使用。
- GDB(GNU 调试器)GUI
- Emacs——Emacs 编辑器内置了对 GNU 调试器的支持,充当前端。
- KDbg——KDE 开发工具的一部分。
- Nemiver——一个 GDB 前端,可以很好地集成到 GNOME 桌面环境中。
- xxgdb——GDB 和 dbx 调试器的 X 窗口前端。
- Qt Creator——GDB 的跨平台前端(调试示例)。
- cgdb——模拟 vim 键映射的 ncurses 终端程序。
- ccdebug——使用 Qt 工具包的图形 GDB 前端。
- Padb——具有与 GDB 平行的前端,使其可以针对并行应用程序。
- Allinea 分布式调试工具——修改后的 GDB 版本的并行和分布式前端。
- Xcode——也包含 GDB 前端。
- SlickEdit——也包含 GDB 前端。
- Eclipse C/C++ 开发工具 (CDT) [2]——包括基于 GDB 的可视化调试工具。
- Jonathan B. Rosenberg, How Debuggers Work: Algorithms, Data Structures, and Architecture, John Wiley & Sons, ISBN 0-471-14966-7