-
Notifications
You must be signed in to change notification settings - Fork 7
1 调试器原理概述
想必在Linux下进行开发工作的同学对GDB(GNU Project debugger)都不陌生。当遇到程序的执行结果不符合预期时,除了在相关位置添加日志输出中间状态外,使用GDB对程序进程调试也是一个很好的排查方法。那么,如何定义调试器呢?下面是维基百科对调试器(Debugger)的定义:
A debugger or debugging tool is a computer program that is used to test and debug other programs (the "target" program). The code to be examined might alternatively be running on an instruction set simulator (ISS), a technique that allows great power in its ability to halt when specific conditions are encountered, but which will typically be somewhat slower than executing the code directly on the appropriate (or the same) processor. Some debuggers offer two modes of operation, full or partial simulation, to limit this impact.
值得一提的是,现代的调试器往往都不再使用ISS(Instruction Set Simulator, 指令集模拟器)方式进行调试了,而是相关的平台(或者说体系结构)已经提供了相关的机制来辅助调试器直接在真实的硬件上运行被调试程序。后续的章节里会具体阐述x86_64架构和Linux系统所提供的调试相关的特性。
现代的调试器一般基于CPU的异常机制,并需要操作系统的异常处理子系统协助。每当调试器程序捕获到一个异常之后,将会根据调试器的自身逻辑来判定是否需要处理这个异常。当调试器处理这个异常时,将根据用户的需求进行相关的操作。处理完毕后调试器程序通知操作系统已经处理完毕,进入下一轮的处理过程。
除了这个方式以外,调试器的实现方式也可以是完全的模拟执行被调试程序。这样的实现方式支持不同架构的代码调试,例如在x86架构上调试ARM的程序。如果你了解虚拟化的一些基本知识的话就很容易理解。而相同架构下调试往往或多或少的都会有一些操作系统乃至硬件参与的虚拟化手段以及调试机制的辅助,以提升调试效率。调试作为软件维护与错误修正的一个最重要、最直接,也是必不可少的一种机制,CPU的制造商也在物理结构上支持着调试这种行为。
- 控制程序运行
- 通过软件/硬件断点等手段,可以随时暂停和执行被调试程序
- 查看程序运行中的信息
- 包含但不限于查看被调试程序当前线程的寄存器、堆栈、内存、反汇编等
- 修改程序执行流程
- 通过修改寄存器、堆栈、内存、反汇编等方式控制被调试程序流程