周报(2026-03-23 至 2026-03-29)
开发分支
- axvisor: https://github.com/Iscreamx/axvisor/tree/feature/ebpf
- axebpf: https://github.com/Iscreamx/axebpf/tree/main
总结
这周正式提交的内容不算多,但方向比较集中,基本都围着 Linux guest uprobe/uretprobe 往前推了一步。现在这条链路已经不只是“能挂上 probe”,而是把返回探针、进程隔离,以及 shell 侧的实例可见性都补到了能拿来稳定排查问题的程度。
如果只看当前已经落进仓库的结果,可以把它概括成一句话:guest uprobe/uretprobe 已经能覆盖 QEMU AArch64 上 Linux guest 主程序用户态探针的主要路径,主程序场景下的基础 ASLR 适配和按进程隔离也已经具备,但对象模型还停留在“主程序文本段”这一层,暂时还没有进入共享库和完整动态装载语义。
一、已完成工作
1. Linux guest uretprobe 主链路接入
- axebpf 返回探针实现(
6c7917b):补上 Linux guest uretprobe 的核心流程,新增 return stack,补齐 entry/return 两段命中处理,并把相关测试一起补上。 - axvisor 主仓接线(
196b447):shell 侧把uretprobe视为uprobe事件族的一部分,trace stream过滤条件现在可以直接覆盖PROBE_UPROBE和PROBE_URETPROBE,跑验证时不用再靠其他类型绕过去看事件。
2. guest-uprobe 实例元数据与进程隔离继续收口
- 按进程 mm 隔离实例(
409dab0):同一个 probe 模板现在可以按不同mm/pid/tgid激活为独立实例;进程退出、exit_mm后也能按目标进程清理,uretprobe 的返回栈状态同样按mm维度隔离。 - shell
列表信息补全(
5c0eaf8):trace list现在除了路径、符号、offset、状态和命中次数,还能直接看到 active uprobe 对应的mm、pid、tgid和comm。排查“为什么同一个符号挂了多个实例”“当前 hit 到底来自哪个进程”时,信息终于够用了。
3. 当前 guest-uprobe/uretprobe 的能力边界
- 现阶段主线能力已经比较明确:在 Linux guest on QEMU AArch64
场景下,主程序用户态探针链路已经基本可用,核心实现集中在
modules/axebpf/src/probe/uprobe/mod.rs。 - host 侧已经支持侧载 ELF 符号元数据,并按
(vm_id, guest_path)把符号解析到文件内 offset;guest 侧则通过隐藏的 guest-kprobe 观察exec、mmap、munmap、exit_mmap、exit这些事件,去维护用户态运行时映射并驱动 probe 激活。 - ASLR 目前也不是完全没处理。对“主程序映射基址变化”这类情况,当前实现已经能把文件 offset 正确映射到运行时地址,相关测试也覆盖了等待主程序真实映射起点出现之后再激活 probe 的路径。
- 但这套模型目前只维护主程序文本段这一条映射,不维护一个进程里的多对象映射集合。换句话说,现在处理的是主程序级、单映射级的 ASLR,而不是完整对象级的 ASLR 语义。
- 这也意味着共享库还不在当前支持范围内。现有逻辑通过
guest_path basename == comm去识别主程序,所以libc.so、libpthread.so、dlopen动态加载的.so目前都不会进入可匹配集合。 - 另外,对象身份机制现在主要还是依赖
guest_path,还没有 build-id、inode 这类更稳的标识;断点语义也还是第一阶段方案,也就是“断点可能对同 VM 的共享代码页可见,但事件按进程过滤”,还不是 Linux 原生那种严格的 pid 级断点隔离。
二、遇到的问题与解决方案
2.1 uretprobe 已经能命中,但缺少足够的实例上下文,排查成本偏高
问题:在 uprobe/uretprobe
开始进入多进程、多实例场景后,只看路径、符号和命中次数已经不够了。尤其是同一个主程序被多次激活时,很难快速判断
active probe 到底对应哪个进程。
解决方案:5c0eaf8 把 shell
列表视图补齐到实例级,直接暴露
mm、pid、tgid 和
comm,把“有没有激活”“是谁激活的”“当前 hit
来自谁”放到一个视图里看。
2.2 同一 probe 模板在多进程场景下需要真正拆成独立实例
问题:如果只按 probe 模板管理
guest-uprobe,主程序多进程并发时会把不同进程的激活态、清理时机和返回栈状态搅在一起,后面再补隔离会很被动。
解决方案:409dab0 把实例粒度下沉到
mm 维度,同一个模板可以按不同 mm/pid/tgid
激活为独立实例;退出路径和 uretprobe 返回栈也一起按 mm
收口,隔离语义总算和当前实现对齐了。
2.3 当前 ASLR 适配只够覆盖主程序,不够覆盖完整对象模型
问题:现阶段已经能处理主程序 load
bias,但共享库各自独立的 load bias、重定位后地址,以及
dlopen
带来的动态装载生命周期,都还没有纳入统一模型。对象匹配也主要靠
guest_path,复杂运行时场景下不够稳。
现状处理:这一周没有继续把范围扩大到共享库,而是先把主程序场景下的链路、隔离和观测信息做扎实。也就是说,当前阶段先把“主程序可用”做稳,再考虑把对象模型从单映射扩到多对象。
三、下周计划
| 优先级 | 任务 | 验收标准 |
|---|---|---|
| P0 | 固化 Linux guest uprobe/uretprobe 的 fresh-run 验证流程 | 主程序场景下 attach、hit、detach、日志校验可一键复现 |
| P1 | 评估共享库支持所需的对象模型扩展 | 明确多对象映射表、对象身份标识、动态装载事件管理需要补哪些状态 |
| P1 | 评估严格 pid 级断点隔离的实现代价 | 明确当前“事件按进程过滤”的阶段性方案与 Linux 原生语义之间还差哪些机制 |