项目阶段工作#


第一阶段:2022-2023#

核心目标:从零构建操作系统源代码级调试工具,打通内核/用户态联合调试的基本链路。

基础框架搭建#

  • 基于 WebFreak001/code-debug(一个开源的 GDB/LLDB 调试前端)进行 fork,在其基础上扩展操作系统调试能力
  • 实现 VS Code 扩展的基本架构:通过 DAP 协议与 VS Code 调试界面交互,通过 GDB/MI 接口控制 GDB
  • 支持 QEMU 虚拟机环境下的远程调试

内核态/用户态联合断点调试#

  • 提出并实现断点组的核心概念:将用户设置的 GDB 断点按所在的地址空间分组,在任意时刻下只有当前地址空间对应的断点组生效
  • 实现断点组切换时的符号表动态加载/卸载:切换地址空间时自动卸载旧符号表、加载新符号表
  • 实现内核态 ↔ 用户态的边界检测与自动切换
  • 以 rCore-Tutorial 作为首个适配目标,验证联合调试的可行性

eBPF 动态跟踪调试#

  • 实现 eBPF 调试面板(WebView)
  • 实现基于 eBPF 的内核态、用户态代码动态跟踪,与 GDB 静态断点调试形成互补

调试界面与交互#

  • 实现 WebView 面板,提供 eBPF 调试的可视化操作界面
  • 实现内存读写功能,寄存器查看功能(RISC-V 寄存器),在侧边栏 TreeView 中展示
  • 实现断点表的可视化展示

本阶段遗留的问题#

在完成核心功能验证的同时,也暴露出了很多问题:

  • 调试器自动设置的断点不会在 VS Code 中显示出来
  • 边界断点的实现逻辑不具有普适性(与内核符号表耦合)
  • 代码实现复杂,不易维护和扩展
  • 没有实现单步步进功能,Continue 按钮不能适用于所有情况
  • 控制台输出杂乱且不完整
  • 编译后的插件包体积过大
  • 配置文件中存在大量硬编码

第二阶段:2023-2024#

核心目标:全面完善调试器的可用性和通用性,扩展对不同语言(C 语言)和不同运行环境(真实硬件)的支持。

A. 调试器功能完善#

针对第一阶段遗留的问题逐一修复:

1. 断点显示问题

  • 利用 VS Code 新增的 debug.addBreakpoints API,使调试器自动设置的断点能够在 VS Code 界面中正确显示,解决了插件与 VS Code 的断点同步问题

2. 边界断点重构

  • 将边界断点从独立模块改为断点组的属性,逻辑上独立但数据结构上附属于断点组
  • 支持通过 customRequest 动态设置/取消边界断点
  • 新增右键菜单操作:在行号右键即可将断点设为边界断点或取消边界

3. 状态机架构重构

  • 引入 OSStateMachine 状态机架构,将复杂的内核/用户态切换流程建模为 4 种状态和 5 种事件的状态转移图
  • 定义明确的 DebuggerActions(8 种动作),每次状态转移触发对应的动作序列
  • 显著提升了代码的可读性、可维护性和可扩展性

4. 单步步进

  • 实现 stepstepInstructionstepOut 等单步操作
  • 支持在内核/用户态边界自动执行逐指令单步(consecutive single steps),直到 PC 进入目标地址空间

5. Continue 按钮适配

  • 改进不依赖跳板页的调试策略
  • 通过内存地址范围判断当前所处的特权级(内核态/用户态),自动检测特权级变化

6. 控制台输出优化

  • 改进 GDB/MI 输出的解析和展示
  • 提供清晰的停止原因提示和状态信息

7. 插件包瘦身

  • 在打包时排除 docs/ 文件夹、演示视频等大型文件
  • 通过 .vscodeignore 配置,大幅减小 .vsix 安装包体积

8. 配置文件去硬编码

  • 支持 ${workspaceFolder} 等 VS Code 变量的自动替换
  • 将硬编码的文件路径、行号等移入 launch.json,由用户自行配置
  • 引入 filePathToBreakpointGroupNamesbreakpointGroupNameToDebugFilePaths 两个映射函数,用户可在 launch.json 中自定义文件路径与断点组的对应关系

B. 新增功能#

钩子断点(Hook Breakpoints)

  • 实现可在断点触发时执行自定义 JavaScript 函数的钩子断点机制
  • 核心用途:在内核进程调度代码处设置钩子,自动获取下一个即将被调度的用户进程名称
  • 钩子函数的返回值用于设置 nextBreakpointGroup,使调试器知道即将切换到哪个用户进程

SSH 远程调试

  • 恢复并完善 SSH 远程调试功能
  • 支持密钥/密码认证、X11 转发
  • 实现远程/本地源文件路径自动映射

多进程调试

  • 实现 initproc-usershell 多进程调试支持
  • 断点组可以动态创建,支持同时调试多个用户态进程

发布到扩展市场

  • 更名为 “OS Debugger”,发布到 VS Code Extension Marketplace
  • 配置 GitHub Actions 自动化构建和发布流程
  • 发布 v2.0.0 里程碑版本

C. C 语言操作系统(xv6)适配#

将调试器的适用范围从 Rust (rCore) 扩展到 C 语言 (xv6):

界面适配

  • 修改 package.json,使调试工具栏对所有语言可见(不再局限于 Rust 文件)

多边界断点支持

  • xv6 在 usys.S 中有多个 ecall 指令(多个用户态出口),不同于 rCore 的单一出口
  • 将边界断点数据结构从单个对象扩展为数组,支持一个断点组拥有多个边界断点

xv6 调试配置

  • 编写针对 xv6 的 launch.json 配置模板
  • 适配 xv6 的 QEMU 启动参数(virt 机器、128M 内存、2 SMP 核心、virtio 块设备)
  • 适配 xv6 用户程序的命名规则(编译后格式为 _filename

钩子断点适配

  • 将钩子断点设置在 xv6 的 sysfile.c exec 函数调用处
  • 通过钩子函数获取下一个用户进程的名称

D. 真实硬件调试支持(昉·星光 2 开发板)#

将调试器从 QEMU 虚拟环境扩展到真实 RISC-V 硬件:

框架搭建

  • 通过 JTAG 接口集成 OpenOCD,OpenOCD 作为 GDB 与硬件之间的中间层
  • 实现 U-Boot 加载操作系统的调试流程

硬件部署

  • 完成 JLink 连接、串口配置等硬件部署工作
  • 编写硬件调试的编译和操作流程文档

硬件适配

  • 实现内核态单步调试
  • 适配 DCSR 寄存器的限制(不支持修改 stepie 字段)
  • 将边界断点调整为设置在 ecall 前一条指令(而非 interrupt handler 入口),以规避硬件限制

E. 工程化改进#

  • 支持 RISC-V 汇编文件的断点设置
  • 引入寄存器查看功能(从上游合并)
  • 编写自动化安装脚本(Shell),支持一键安装所有调试所需的工具和库
  • 合并上游(WebFreak001/code-debug)的多项改进:静态变量支持、STL 容器解析修复、GDB Frame Filters 支持、变量类型显示修复等

第三阶段:2024-2025#

核心目标:提升调试器的稳定性和实用性,修复实际使用中的关键 bug,整理项目仓库,开展 Rust 异步调试功能的研究与开发。

Bug 修复与稳定性提升#

  • 修复"只能调试到一号进程"的问题,使多进程调试能力真正可用
  • 发布 v2.0.1 修复版本

仓库整理#

  • 重新组织项目文件结构,整理历史文档和工作记录
  • 完善安装说明文档

新方向探索#

  • 开展 Rust 异步调试功能的研究与开发