V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
swananan
V2EX  ›  程序员

写了一个基于 eBPF 和二进制调试信息的用户态追踪工具,站在 GDB 肩膀上,但可以对线上服务实时追踪

  •  
  •   swananan ·
    swananan · 1 天前 · 1132 次点击
    项目地址: https://github.com/swananan/ghostscope

    大家感兴趣可以看 README 的演示,我目前可以拿来跟踪 nginx 进程,用的还是蛮顺手的,这个工具我想了好久了,特别是 TUI 操作的时候,加上了我喜欢的 cgdb 、tmux 、vim 甚至还有 emacs 等工具的一些操作风格和按键习惯。所以,我在开发的时候,还是蛮开心的。

    想做这个工具,主要是我以前排查问题的时候,总是觉得日志不够用,但是线上服务,又不能随便发版本,各种红线和变更要求,条条框框卡的很死。我好久以前尝试拿着 systemtap ,根据调试信息去抓线上我想看的信息,属于强行死马当活马医(问题如果拖着不查,后面暴雷了也是一个死😂)。记得,我当时测试机跑宕机了两次,我才敢拿着 systemtap 脚本去小流量机器偷偷抓信息。现在 eBPF + uprobe 的抓取方式,至少安全性是靠谱的。

    不过目前项目还在启动阶段,有蛮多的限制,具体文档有写。我这边简单提两句,对 c 语言支持比较好(有点废话的意思😁),至于 C++、Rust 的话,目前只简单支持了 mangled 查找,各种高级语言特性完全不支持。另外,对于编译器开了高优化的程序,探测能力还有待后续增强,各种内联,调试信息 DWARF 复杂好多,搞得我头大。

    大家有什么想法,欢迎开 issue 或者在帖子留言,我还在疯狂迭代,准备先让自己觉得好用,后面再看下一步迭代方向。
    13 条回复    2025-10-13 20:20:14 +08:00
    faketemp
        1
    faketemp  
       1 天前 via iPhone
    👍 请问下对比 bpftrace 在使用方法和功能等方面有哪些优势?另外 windows 系统下除了 frida 有没有类似大佬这种可以实时追踪的工具推荐?
    illios
        2
    illios  
       1 天前   ❤️ 1
    Very impressive work ! STARed on github
    bv
        3
    bv  
       1 天前
    swananan
        4
    swananan  
    OP
       1 天前
    @faketemp
    问题 1:这是个很好的问题哈,我这边做个回答(晚上我整理一下,给放到项目 QA 文档里面)。
    a. bpftrace 在最近的版本变动里面去掉了对 DWARF 也就是调试信息的支持( https://github.com/bpftrace/bpftrace/pull/3921 )。这也是我想启动这个项目的一个原因之一。

    b. bpftrace 对 DWARF 的使用,应该是局限在复杂数据结构的内存布局上面,增强对复杂数据结构的访问。但是,bpftrace 只支持了函数入口和函数返回这种 hook 点,没有完全利用 DWARF 的能力。比如说,某一行源码对应的指令,被探测程序执行到这个指令时候,局部变量,全局变量,参数究竟在内存的哪里。这些是需要根据 DWARF 里面的表达式进行实时求值,才能获取到的。这意味着 bpftrace 其实无法具备类似于 GDB 那样基于 DWARF 提供完整的用户态探测调试的能力。 (我对 bpftrace 代码了解的很粗浅,只是以前快速翻了一下,有错误随时指正哈)

    c. ghostscope 参考 GDB 对 DWARF 的处理,并且把 DWARF 表达式实时生成 LLVM IR ,然后通过 LLVM 生成 eBPF 字节码。这样的话,理论上 ghostscope 是可以根据 DWARF 描述的信息,在用户关注的指令流程上,抓取正确的二进制数据,并且正确的根据 DWARF 信息展示出二进制数据对应源代码的样子。当然,因为 ghostscope 底层依赖的是 eBPF + uprobe ,而不是像 GDB 那样使用 ptrace ,所以不能提供交互式 debug 的体验,但是不影响进程服务运行,而获取关键信息的能力,在很多时候是很有用的。

    d. ghostscope 提供了我个人非常喜欢的 TUI 使用方式,类似于 cgdb ,哈哈,我是真的喜欢 cgdb ,我觉得也许也会有其他人喜欢吧。

    问题 2:我不太懂 Windows 系统,我甚至还没有去了解 Windows eBPF 的进展( https://github.com/microsoft/ebpf-for-windows ),也不太清楚 Windows 有没有类似 uprobe 的机制。但是我有一个想法,就是类似 bpftime 的方式,hack 进用户态进程里面,然后执行 eBPF 脚本。不晓得有没有类似的项目在做这件事情。如果我把 ghostscope 打磨稳定(支持好编译高优化程序的 DWARF 、支持栈回溯、支持 Rust 或者 C++ 的一些高级特性),我可能会开始考虑跨平台方案。我还在学习的路上,工作也不是专门做这块的,所以应该还是要踩坑和探索好久。
    swananan
        5
    swananan  
    OP
       1 天前
    @bv 感谢提醒,我说为啥 workflows 一直没跑,我以为是需要充钱,哈哈,我晚上回去处理一下。
    我第一次发布工具类的项目,我本意是想尽量支持更多的系统版本,所以我选了 Ubuntu 20.04 来进行构建。
    现在的话,我是通过 docker 来构建的(还是基于 Ubuntu 20.04 ),然后构建的二进制 tar 包在 Release 页面里面。
    csfreshman
        6
    csfreshman  
       1 天前   ❤️ 1
    已 star ,有空学习下
    buleLi
        7
    buleLi  
       1 天前
    这里使用了 uprobe ,那启动时实际上会造成目标进程的上下文切换,如果 attach 的位置是一个高频函数,那性能影响应该比较大?
    zzz22333
        8
    zzz22333  
       1 天前
    有点意思,我之前尝试用 ftrace+kprobe 去抓函数传入的参数,但是效果不尽人意。
    wsszh
        9
    wsszh  
       1 天前
    厉害了,学习下
    zzz22333
        10
    zzz22333  
       1 天前   ❤️ 1
    @zzz22333 #8 我也喜欢用 cgdb ,我研究研究,看后续加点 feature
    swananan
        11
    swananan  
    OP
       1 天前
    @buleLi 是的,如果在热点路径加,性能影响会比较大,本质上这个开销比起代码中打印日志,还多了上下文切换。不过,调试排查问题,不太应该在热点路径狂加日志(至少加点过滤条件)。后续优化的话,比较倾向于接入 bpftime ,来避免上下文切换的开销。
    swananan
        12
    swananan  
    OP
       1 天前 via iPhone
    @zzz22333 欢迎欢迎,我挺喜欢 cgdb 模式切换,以及源码上直接加断点的(虽然这么一说,平平无奇的样子),但是 vim 风格操作我非常喜欢
    zzz22333
        13
    zzz22333  
       1 天前 via Android
    @swananan 我是之前同事推荐的,cgdb 操作跟 vim 差不多,我是分了左右界面,左边看代码,右边操作
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3013 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 13:22 · PVG 21:22 · LAX 06:22 · JFK 09:22
    ♥ Do have faith in what you're doing.