GhostScope 教程
July 1, 2026 · View on GitHub
10 分钟学会使用 GhostScope 追踪运行中的应用程序!
快速开始
从 AI 辅助追踪开始
如果你正在同一个 workspace 里使用 Codex 或 Claude Code,最快的上手方式通常是先让共享的 ghostscope-runtime-analysis skill 帮你生成第一版 attach 命令和追踪脚本,然后再回到 TUI 里做检查和微调。
先安装这个 skill:
curl -fsSL https://raw.githubusercontent.com/swananan/ghostscope/main/scripts/skills/install_ghostscope_runtime_analysis_skill.sh | bash -s -- --copy
如果你已经把仓库 clone 到本地,也可以继续使用 ./scripts/skills/install_ghostscope_runtime_analysis_skill.sh --copy。
然后直接提一个具体的追踪需求:
$ghostscope-runtime-analysis 跟踪正在运行的 nginx worker,并把请求 body 的原始字节打印出来
如果你想看的不只是变量值,而是调用上下文,可以直接要求输出调用栈:
$ghostscope-runtime-analysis 跟踪正在运行的 nginx worker,展示哪个请求到达了 ngx_http_process_request,并输出源码感知的调用栈
这条路径特别适合想先拿到一套可复用的 --script-file CLI 工作流的人。AI 给出初版之后,TUI 仍然是查看源码、微调设点和迭代脚本的最佳位置。如果你想继续了解 GhostScope 的具体使用细节,也可以继续参考下面的教程。
启动 GhostScope
GhostScope 提供两种模式来附加到进程,两者都使用 Linux uprobe + eBPF 机制:
模式 1:特定 PID 追踪(-p)
# 通过 PID 追踪特定的运行进程
sudo ghostscope -p $(pidof your_app)
- 使用场景:您有一个运行中的进程,只想追踪该特定实例
- 优势:专注追踪,减少来自其他进程的噪音
- 限制:无法捕获早期启动事件
模式 2:全二进制追踪(-t)
# 追踪所有使用此二进制文件的进程
sudo ghostscope -t /path/to/binary
# 也适用于共享库
sudo ghostscope -t /usr/lib/libexample.so
- 使用场景:您想捕获进程启动事件或追踪多个实例
- 优势:可以捕获进程初始化的事件,非常适合调试启动问题
- 注意:独立
-t默认启动 sysmon,并会追踪所有使用此二进制文件/库的进程,可能会产生更多事件。可在配置中设置enable_sysmon_for_target = false关闭独立-t的 sysmon。 - 限定 PID 的目标模式:如果想使用
-t /path/to/module的模块目标解析,但只观察一个运行中进程的事件,可以使用-t /path/to/module -p <PID>。这种形式下目标解析以-t为准,-p提供 PID 过滤和 watched-PID 模块刷新。
重要说明
⚠️ 注意事项:
-p选项会追踪指定进程。bt可以为后续通过dlopen加载的库刷新模块元数据,但新增 trace probe 仍依赖 setup 阶段已经知道目标模块。- 您想追踪的可执行文件和动态库必须包含调试信息,否则 GhostScope 将无计可施。如何判断调试符号是否存在?请参考安装指南的调试符号章节
了解 TUI 界面
启动和加载
成功执行启动命令后,您会看到一个加载界面 — GhostScope 正在加载调试信息并建立查询索引。这可能需要一些时间(比如加载 nginx 大约需要 3 秒)。别问我为什么 GDB 加载那么快,我还在努力向 GDB 学习优化技巧,争取后面版本能更快一些。
GhostScope 精心设计的加载界面
如果一切顺利,只需一眨眼的时间(可能会因此错过精心设计的加载界面),我们就会看到 GhostScope 的 TUI 界面:
GhostScope TUI 主界面
三大面板
简单介绍一下 GhostScope 的 TUI 面板构成:
1. 源代码面板
- 显示内容:应用程序的源代码(默认展示 main 函数所在的代码文件)
- 用途:浏览代码并设置追踪点
2. eBPF 输出面板
- 显示内容:实时追踪输出
- 用途:查看实时发生的执行追踪
3. 命令交互面板
- 显示内容:命令输入行
- 用途:输入追踪命令和控制会话
核心操作
这里展示两种最主要的使用方式,也就是 README 中 demo 所演示的内容。
命令交互面板的三种模式
焦点默认在命令交互面板,该面板有三个模式:
1. 输入模式(默认)
在输入模式下,您可以执行各种命令。例如:
trace {target} # target 可以是函数或源码行号
详细命令语法请参考命令参考。
2. 脚本模式
按回车后进入脚本模式,开始编写 GhostScope 脚本来探测进程:
- 使用
print打印局部变量、参数甚至全局变量 - 只要 DWARF 信息包含变量描述,就能获取有意义的数据
- 支持定义脚本变量和简单的判断逻辑
- 更多脚本语法细节请参考脚本语言参考
脚本编辑模式
编写完成后,按 Ctrl+S 提交代码。如果一切顺利,脚本会被编译成 eBPF 字节码并加载到 uprobe 上。
脚本执行结果
3. 命令模式
这个时候,如果一切顺利,我们将在 eBPF 输出面板上看到脚本对应的输出。但要查看输出,我们需要把焦点切换到 eBPF 输出面板。
eBPF 输出结果
按 Esc 从输入模式切换到命令模式,在这个模式下:
- Vim 风格导航:使用
hjkl浏览历史消息(灵感来自 cgdb) - 回到输入模式:按
i键 - 面板切换:
Tab/Shift+Tab:在面板间切换Ctrl+W+hjkl:Vim 风格的面板跳转(Vim 爱好者的福音 😁)
面板操作技巧
eBPF 输出面板
当焦点在 eBPF 输出面板时,同样支持 Vim 风格的导航和快速移动。
全屏模式
如果面板太小,除了启动时设置比例,还可以:
- 按
Ctrl+W z:将当前焦点面板全屏(这招从 tmux 学来的,也是我的最爱 😉)
💡 推荐的工作流程
更高效的使用方式是从源代码面板开始:
- 浏览源码:把焦点切换到源码面板,使用 Vim 风格导航浏览代码
- 切换文件:按
o键唤出文件搜索栏,快速查找并切换到其他源码文件 - 快速设置追踪点:当看到感兴趣的代码行时,按空格键直接进入脚本模式
- trace 的 target 会自动设置为光标所在的文件和行号
- 这个设计灵感来自 cgdb,我非常喜欢这种快捷方式
这样的工作流程更加流畅,让追踪点的设置变得轻而易举。
💡 查看追踪点可用变量
在设置追踪点之前,如果想知道某个位置可以访问哪些局部变量和参数,可以使用 info 命令:
info line <file:line> # 查看源码行的可用变量
info function <func_name> # 查看函数入口的可用变量
info address <0xADDR> # 查看地址的可用变量
这些命令会显示该位置的调试信息,包括可访问的变量列表:
使用 info line 命令查看可用变量
使用脚本文件
为了重复使用,我们可以将追踪脚本保存在文件中:
# trace.gs
trace calculate_something {
print "FUNC: a={} b={}", a, b;
}
trace sample_program.c:16 {
print "LINE16: result={}", result;
}
我们既可以通过命令行直接运行它:
sudo ghostscope -p $(pidof your_app) --script-file trace.gs
我们也可以在 TUI 的命令交互面板上,通过 source <脚本名称> 的方式直接加载脚本:
使用 source file 命令直接加载脚本
💡 小贴士:在 TUI 中设置了多个追踪点后,可以使用 save trace <文件名> 命令将所有当前追踪点保存到文件中,方便后续复用。详见命令参考。