
笔记整理自 b 站 up 主,谢谢 up 分享 :https://www.bilibili.com/video/BV1r4itBNEF2
一、GDB 简介
GDB(GNU Debugger) 是一款开源调试工具,支持多种编程语言(如 C、C++、Python 等),主要用于在程序运行时检查其状态,包括变量值、内存布局、调用堆栈等。它可以帮助开发者定位逻辑错误、内存泄漏、段错误等问题。
使用 GDB 调试程序的前提:
- 操作系统内核通过 ptrace 提供对其他进程内存的读写能力
- 使用 CPU 提供的调试指令修改内存的位置
- CPU 执行产生调试异常,操作系统把异常转发给 GDB 处理
| x86 / x86_64 | int3 |
| ARM (32-bit) | BKPT |
| ARM64 | BRK |
| RISC-V | EBREAK |
| MIPS | BREAK |
二、ptrace 系统调用
ptrace 是 Linux/Unix 系统里的一个核心系统调用,主要用来让一个进程去跟踪和控制另一个进程的执行。

如何实现得到变量的值
假设使用 GDB 调试程序 ./a
- 启动目标程序 ./a 作为子进程。
- 调用 ptrace(PTRACE_TRACEME, …) 将自身标记为可被跟踪状态。
- GDB 作为父进程运行,负责接收用户的调试指令。
- GDB 通过调用 ptrace 系列 API(如 PTRACE_PEEKTEXT, PTRACE_GETREGS 等)来读取子进程的内存或寄存器状态。

如何实现打断点
将目标地址处的原始指令的第一个字节替换为 0xCC(即 x86 架构下的 int3 指令)。当 CPU 执行到该指令时,会触发 #BP (Breakpoint) 异常,从而陷入内核态。
CPU 触发中断 —— 内核处理中断 —— 还原原始代码 —— 调整指令指针(RIP)
- CPU 触发中断:CPU 执行到 0xCC,触发 #BP 异常,控制权移交操作系统内核。
- 内核处理中断:内核识别出这是由调试器设置的断点(通过检查进程状态),暂停目标进程(Tracee),并向调试器(Tracer,如 GDB)发送 SIGTRAP 信号。
- 还原原始代码:调试器收到信号后,先将之前备份的原始指令写回内存地址,覆盖掉 0xCC。
- 调整指令指针(RIP):将程序计数器(RIP/EIP)回退 1 个字节(因为 CPU 已经执行了 int3,RIP 指向了下一条指令,必须指回原指令开头)。
三、DWARF 调试信息格式
- debug_line:记录行和行数的映射关系
– 程序信息记录

MI 协议
GDB/MI(GDB Machine Interface) 是GDB提供的一种面向程序、而不是人类的调试接口协议。它的目标是:让IDE、调试前端、自动化工具能可靠可解析地控制GDB,而不需要去解析人类可读的CLI输出。

RSP 远程串行协议
RSP 是 GDB 与远程目标之间通信的标准协议。在远程调试场景中,GDB 作为客户端(Host),GDB Server 作为服务端(Target),两者通过 TCP/IP 或串口交换 RSP 数据包。
- 将用户的CLI命令(break a.c:6)转换为 RSP 命令(Z0,addr,kind)
- 解析DWARF,管理符号
- 计算栈回溯
- 解析来自 GDB Server 的结果,展示出来
- 解析来自 RSP 的命令,转换执行对应的 ptrace 命令
- 再把结果发送回 GDB

四、补充
现代处理器可以同时多发射指令

使用处理器精确中断解决该问题(ROB 重排缓冲区),该功能实现在最后修改值时判断前面的指令是否执行完。

解释型语言的调试
Python
- 核心 API:sys.settrace(func),通过该函数注册一个跟踪回调函数,VM 会在特定事件发生时调用它。
- 调试原理
Java (JVM 体系)
- 调试器前端 (Debugger)
工具:IntelliJ IDEA, Eclipse, jdb 等。
接口:JDI (Java Debug Interface)。这是给开发者使用的高级 API。 - 传输层 (Transport)
协议:JDWP (Java Debug Wire Protocol)。
作用:定义调试器与目标 JVM 之间通信的数据包格式(如“设置断点”、“读取变量”的具体二进制指令)。 - 后端代理 (Agent & VM)
JVM Debug Agent:运行在目标 JVM 进程中的组件。
JVMTI (JVM Tool Interface):Agent 通过此接口与 JVM 内核交互。它是 JVM 暴露给外部工具的标准原生接口。
JVM 内核:包含解释器和 JIT 编译器。
当内核执行到特定位置(如断点指令),触发事件回调 -> 上报给 JVMTI -> Agent 封装为 JDWP 消息 -> 发送给前端调试器。