bpftrace 用户态探针

对应用二进制函数插桩, 观测用户态调用频率与返回耗时, 无需重启应用。

用户态探针

用户态探针在应用程序的函数上插桩,观测调用频率与返回耗时。它不需要重启应用、不需要改代码、也不依赖应用自带埋点,对第三方组件尤为实用。目标可以是二进制的符号名,也可以是符号缺失时的地址偏移。

基本信息

适用平台Linux,需要内核 eBPF 支持与相应权限
目标形式二进制路径加符号名,或路径加偏移
符号要求符号需存在于二进制,或被剥离时改用偏移
开销高频热函数插桩会明显增加开销
稳定性二进制更新后符号与偏移可能变化

典型使用场景

  • 观测第三方组件内部函数的调用频率,缺少官方指标时尤其有用。
  • 统计业务关键函数的调用次数,验证上线后的实际路径。
  • 测量函数耗时分布,定位比预期慢的那一类调用。
  • 确认某个配置开关对应的代码分支是否被走到。
  • 在无法重新部署的环境里做只读观测。

用法

用法
bpftrace -e 'uprobe:/opt/app/bin/server:handle_request { @ = count(); }'   # 调用次数
bpftrace -e 'uprobe:/opt/app/bin/server:handle_request { @start[tid] = nsecs; }
uretprobe:/opt/app/bin/server:handle_request { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }'   # 耗时分布
nm -D /opt/app/bin/server | grep -i handle_request    # 先确认符号是否存在
readelf -sW /opt/app/bin/server | grep -c FUNC        # 查看符号表规模
bpftrace -e 'uprobe:/opt/app/bin/server:0x1234 { @ = count(); }'   # 无符号时用偏移

指定方式

形式写法适用情况
按符号名路径加冒号加函数名二进制保留符号表
按偏移路径加冒号加十六进制地址符号被剥离或静态符号
动态库函数库文件路径加符号名观测依赖库内部行为
插桩的是内存中的一份二进制:应用发布新版本后,之前写死的符号与偏移需要重新核对,否则探针会挂到错误位置或直接失效。
语言运行时的即时编译代码与动态生成的函数通常不在二进制符号表里,这类目标挂不上用户态探针;需要观测时应改用运行时提供的追踪机制或日志埋点。
对高频热函数插桩会显著放大开销:先用计数模式小窗口试跑,确认影响可接受后再测量耗时分布。

易错点

  • 二进制更新后符号偏移变化,脚本失效或统计到错误位置。
  • 对高频热函数插桩引入额外开销,被测应用行为被改变。
  • 符号被剥离后仍用符号名挂探针,启动失败却没意识到要改用偏移。
  • 把用户态耗时直接当成端到端延迟,忽略排队与网络时间。
  • 忘记核对二进制的构建标识,观测的其实不是线上那份程序。

数据来源与参考

  • bpftrace 官方文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌