mcpField
F
Function Call Tracing

Function Call Tracing

github.com/gadievron开发4.0k122 次安装今天更新
代码仓库

关于 Function Call Tracing

Function Call Tracing 是用于追踪 C 和 C++ 程序函数调用的技能,可记录各线程日志并转换为 Perfetto 可视化格式。它指导编码 Agent 在沙箱中构建、运行不可信项目并转换日志。

主要功能

  1. 01追踪 C/C++ 函数进入与退出
  2. 02按线程记录调用日志
  3. 03转换为 Perfetto 可视化格式
  4. 04通过沙箱执行构建与运行

适用场景

  1. 01检查多线程程序的函数调用
  2. 02在 Perfetto 中查看调用时间线
  3. 03安全追踪不可信项目

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gadievron/raptor --skill function-call-tracing

安装后在 Claude Code 中输入/function-call-tracing确认已加载。

附带文件trace_instrument.ctrace_to_perfetto.cpp

详细介绍

函数调用跟踪

用途

跟踪 C/C++ 程序中的所有函数调用,生成按线程划分的日志并使用 Perfetto 进行可视化。

隔离

被跟踪的项目不可信——其构建脚本和生成的二进制文件都可以执行任意代码。任何运行目标构建系统或经过插桩的二进制文件的命令,都必须通过 libexec/raptor-run-sandboxed --output-dir <dir> <cmd> [args...] 执行(--output-dir = 命令写入的目录:构建时为项目目录,运行时为工作目录)。沙箱会按设计清除加载器变量(LD_LIBRARY_PATH、LD_PRELOAD);经过插桩的链接会将 rpath 写入二进制文件,因此在沙箱中运行时无需设置加载器变量即可解析 libtrace.so。如果沙箱步骤失败,应修复沙箱执行路径——绝不能直接运行目标程序。构建插桩库本身(RAPTOR 自身的技能源代码)无需使用沙箱。

组件

1. 插桩库(trace_instrument.c)

捕获函数进入和退出事件,并写入按线程划分的日志。

构建:

gcc -c -fPIC trace_instrument.c -o trace_instrument.o
gcc -shared trace_instrument.o -o libtrace.so -ldl -lpthread
2. Perfetto 转换器(trace_to_perfetto.cpp)

将日志转换为供 Perfetto UI 使用的 Chrome JSON。

构建:

g++ -O3 -std=c++17 trace_to_perfetto.cpp -o trace_to_perfetto

用法

步骤 1:添加到构建配置

LIBTRACE_DIR 是存放 libtrace.so 的绝对目录;-Wl,-rpath 可让二进制文件在沙箱中运行时找到该库(沙箱会清除 LD_LIBRARY_PATH)。

CFLAGS += -finstrument-functions -g
LDFLAGS += -L$(LIBTRACE_DIR) -Wl,-rpath,$(LIBTRACE_DIR) -ltrace -ldl -lpthread
步骤 2:构建目标(在沙箱中——构建脚本不可信)
libexec/raptor-run-sandboxed --output-dir <project-dir> make ENABLE_TRACE=1
步骤 3:运行(在沙箱中;rpath 可解析 libtrace.so——无需设置加载器变量)
libexec/raptor-run-sandboxed --output-dir <working-dir> <project-dir>/program
# Creates trace_<tid>.log files
步骤 4:转换为 Perfetto 格式(在沙箱中——日志字节来自不可信的目标程序,且转换器是原生代码)
libexec/raptor-run-sandboxed --output-dir <working-dir> ./trace_to_perfetto trace_*.log -o trace.json
# Open trace.json in ui.perfetto.dev

日志格式

[seq] [timestamp] [dots] [ENTRY|EXIT!] function_name
[0] [1.000000000]  [ENTRY] main
[1] [1.000050000] . [ENTRY] helper
[2] [1.000100000] . [EXIT!] helper
[3] [1.000150000]  [EXIT!] main
  • 点号表示调用深度
  • 时间戳格式为秒.纳秒
  • 每个线程对应一个日志文件

用户请求跟踪时

步骤
  1. 将 trace_instrument.c 和 trace_to_perfetto.cpp 复制到项目中
  2. 构建插桩库
  3. 将 -finstrument-functions 添加到 CFLAGS
  4. 将 -L$(LIBTRACE_DIR) -Wl,-rpath,$(LIBTRACE_DIR) -ltrace -ldl -lpthread 添加到 LDFLAGS
  5. 通过 libexec/raptor-run-sandboxed --output-dir <project-dir> ... 构建项目
  6. 通过 libexec/raptor-run-sandboxed --output-dir <working-dir> ... 运行经过插桩的二进制文件(rpath 可解析 libtrace.so)
  7. 通过 libexec/raptor-run-sandboxed --output-dir <working-dir> ./trace_to_perfetto trace_*.log -o trace.json 转换日志(将不可信的日志字节传入原生解析器)
  8. 提供 ui.perfetto.dev 的链接
构建系统检测

Makefile: 按条件添加标志

ENABLE_TRACE ?= 0
ifeq ($(ENABLE_TRACE),1)
    CFLAGS += -finstrument-functions -g
    LDFLAGS += -L$(LIBTRACE_DIR) -Wl,-rpath,$(LIBTRACE_DIR) -ltrace -ldl -lpthread
endif

CMake: 添加选项

option(ENABLE_TRACE "Enable tracing" OFF)
if(ENABLE_TRACE)
    add_compile_options(-finstrument-functions -g)
    link_directories(${LIBTRACE_DIR})
    add_link_options(-Wl,-rpath,${LIBTRACE_DIR})
    link_libraries(trace dl pthread)
endif()

输出

  • trace_.log:按线程划分的文本日志
  • trace.json:Perfetto Chrome JSON 格式
  • 在 https://ui.perfetto.dev 查看

Perfetto JSON 格式

函数 ENTRY → “B”(开始)事件 函数 EXIT! → “E”(结束)事件 所有线程按时间戳对齐并存于同一个文件。

评论

支持 Markdown