You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux平台下如何不阻塞地跟踪运行中用户进程的实时函数调用

Linux 非阻塞式用户态进程函数调用跟踪方案

1. eBPF 方案(首选,低开销、全量捕获支持)

eBPF 是内核原生提供的 tracing 框架,无需依赖 ptrace,不会将目标进程置为暂停状态,常规使用场景下对目标进程的性能开销低于 5%,生产环境可直接使用。

  • 针对特定函数跟踪:使用内核 uprobe(用户态函数探针)+ uretprobe(用户态函数返回探针),可以捕获指定函数的每次入栈、出栈操作,支持同时获取调用栈、参数、返回值等信息。
    示例(基于 bpftrace 工具,跟踪指定 PID 进程的 libc malloc 调用):
    bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /pid == 1234/ { printf("PID %d call malloc, size: %d\n", pid, arg0); }'
    
  • 针对全函数调用栈抓取:配合 ustack 参数可以直接输出完整的用户态调用栈,也可以使用 bcc 工具集的现成工具 funccount、functrace 直接实现进程全函数调用跟踪。

2. PMU 采样方案(无侵入、低开销,适合热点排查)

利用 CPU 硬件性能监控单元的采样能力,通过 Linux 原生 perf 工具实现无阻塞跟踪,完全不会干扰目标进程的运行。
示例(实时采样指定 PID 的用户态调用栈):

# 实时查看调用栈热点
perf top -p 1234 -g -e cycles:u
# 记录10秒采样数据,事后分析全量调用栈
perf record -g -p 1234 -e cycles:u -- sleep 10 && perf script

注意:该方案为采样式实现,无法保证100%捕获每一次函数调用,适合排查性能热点、统计调用占比场景,不适合需要精确记录每次入栈出栈的场景。

3. 用户态插桩方案(灵活度高,适合自定义跟踪逻辑)

如果需要自定义跟踪逻辑,不需要内核权限的场景可以选择该方案:

  • 可提前重启目标进程时:使用 LD_PRELOAD 注入自定义钩子库,在钩子函数中实现入栈、出栈的日志记录,完全运行在用户态,对目标进程无额外阻塞开销。
  • 无法重启目标进程时:使用 dyninst 工具集对运行中的进程进行动态指令插桩,仅在插入钩子时会短暂暂停进程一次,后续跟踪过程完全无阻塞,开销可控。

注意事项

  • 所有跨进程跟踪方案都需要 root 权限才能访问目标进程的符号表、内存信息。
  • 若需要精确捕获每一次函数调用,不要使用非同步的 /proc/pid/stack 遍历方案,会拿到不一致的栈数据,精度无法满足要求。

内容的提问来源于stack exchange,提问作者ANTHONY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 15:54:07