当前位置:首页 > 文章列表 > 文章 > linux > bpftrace profile 探针怎么按固定频率采样用户态堆栈

bpftrace profile 探针怎么按固定频率采样用户态堆栈

来源:17golang原创 2026-11-05 15:24:15 0浏览 收藏

bpftrace 可以用 profile:hz:49 请求固定频率的 CPU 采样,在谓词中按 PID 过滤,再用 @stacks[ustack(20)] = count(); 聚合用户态堆栈。profile 在每个 CPU 上按配置触发;PID 过滤决定哪些采样进入统计,并不保证目标进程每秒一定获得 49 个样本。

官方地址:https://bpftrace.org/docs/release_024/language

最小脚本:采集十秒,只保留目标 PID 的用户栈

将下面内容保存为 user-stacks.bt。它使用 bpftrace 0.24 文档中的语法,适用于具备对应 BPF 与 perf 事件能力的 Linux 环境。示例未在本文执行,没有实际进程的堆栈输出或性能结论。

// user-stacks.bt:面向 bpftrace 0.24 文档语法。
profile:hz:49
/pid == $1/
{
    // 同一用户态堆栈作为一个键,只在内核映射中累加样本数。
    @stacks[ustack(20)] = count();
}

interval:s:10
{
    // 约十秒后请求退出;由 bpftrace 默认退出行为打印聚合映射。
    exit();
}
# 将 4242 替换为 bpftrace 所在 PID 命名空间中可见的目标进程号。
# 仅对有权诊断的进程使用;本例只采样,不启动或终止目标进程。
sudo bpftrace user-stacks.bt 4242

49 Hz 是这个示例选择的起始频率,不是对所有机器推荐的最佳值。ustack 的 20 表示堆栈帧数上限,不是采样次数;interval:s:10 只负责结束采集,不采集目标进程的堆栈。目标进程本身不会因为这个脚本的 exit 被结束。

数据来源:每个 CPU 的采样事件

profile 使用 Linux perf_events。可以按 hz 指定频率,也可以用时间单位指定间隔;这里统一使用 hz,避免把频率数字与毫秒间隔混写。请求固定频率不等于没有调度和事件处理偏差的精密计时器。

采样时 CPU 上正在运行的执行上下文决定当前 pid。目标若在休眠、等待或大部分时间没有被调度运行,过滤后样本会少;目标有多个线程分布在多个 CPU 上运行时,聚合到同一个进程的样本又可能多于单个 CPU 的频率数字。

因此不能拿 49 乘十秒直接要求输出一定有 490 个目标样本。这种采样主要帮助观察目标获得 CPU 执行期间常出现的用户态调用栈,不是完整的阻塞时间分解,也不是每次函数调用的精确追踪。

bpftrace profile 每 CPU 采样与 PID 过滤的静态关系图
静态结构图:事件来源与筛选条件分组说明哪些上下文有资格进入统计,连线不是时间轴,也不代表实测样本量。

进入映射前,明确 PID 的含义

脚本中的 $1 是命令后的第一个位置参数,pid 是采样上下文的进程 ID。按 0.24 文档,默认 pid 对应 bpftrace 所在 PID 命名空间可见的编号。若在容器内外取得了不同的数字,直接比较就可能匹配不到目标;先统一观察和执行所在的命名空间。

pid 过滤会把目标进程各线程的匹配样本放到同一个统计范围;若需要区分线程,可把 tid 加到聚合键中,但这会改变统计维度、增加键数量。不要把进程名 comm 当成唯一身份,多个进程可能同名。

本文选择显式谓词,不依赖附加选项暗中替所有 probe 做过滤。执行前还应确认 PID 对应的目标身份与采样窗口内的生命周期;长时间保存旧 PID 再启动采样,可能已经不是原来的进程。

存储模型:堆栈为键,样本数为值

ustack 返回用户堆栈类型,适合作为 map 键;count 是聚合函数。匹配同一个堆栈键的样本被累加,避免每次 profile 触发都把整条栈 printf 到终端。数据规模主要取决于观察到的不同堆栈数量与配置限制,而不仅仅是总事件数。

元素本例职责不能解释为
profile:hz:49请求每 CPU 的采样频率目标进程必定每秒 49 次
pid == $1筛选目标进程上下文目标每个线程单独输出
ustack(20)最多采集二十帧用户栈二十次调用或二十毫秒
count()同键样本聚合计数函数调用次数或请求数

若两条调用链只在第二十帧以后才不同,有限深度可能让它们在这里呈现相同前缀;增大深度会带来更多采集与存储成本。应先判断目前深度是否足以定位问题,再调整,不把最大深度当成默认目标。

查询与输出:退出时查看聚合结果

bpftrace 默认在程序退出时打印已填充的映射,所以本例无需再写 END 打印一次。interval 到时请求退出,随后正常收尾;退出和输出并非严格实时边界。如果手动中断,也应使用工具支持的正常退出方式,让收尾有机会完成。

读结果时先找样本较多的堆栈,再看是否与目标正在处理的负载相符。某条栈占已采集样本的比例,只是这一轮、这一 PID 与配置下的样本占比,不能直接写成整机 CPU 使用率,也不能单凭某函数出现在栈顶就认定其全部耗时。

bpftrace 用户堆栈聚合键、计数与退出输出静态结构图
静态说明图:聚合数据和收尾职责分组独立,count 表示样本累加;图内没有实际函数名或虚构性能数据。

异常处理:空统计和符号不全要分别看

没有样本时,先分辨是否根本未能附加,还是附加后 PID 没匹配、目标很快退出、窗口内目标没有足够的 CPU 活动。附加失败可能涉及内核支持、BPF/perf 访问策略或运行环境权限,应按管理员授权处理,不通过关闭安全限制来凑出结果。

若有地址但缺少符号,或堆栈明显很短,要分别考虑符号信息和栈展开条件。官方用户栈示例特别提及 frame pointers;目标的编译选项、优化和运行时都会影响可见性。缺失帧不能自动解释成“没有调用上层函数”,也不能把 JIT 语言的本机栈当成完整语言级栈。

采样频率、堆栈深度和映射容量都会影响开销。可以缩短窗口或降低频率来收敛诊断成本,但本文没有测得开销比例,不宣称这套配置对生产环境零影响。

清理与常见追问

本例不归档原始事件,只在内存映射中聚合,退出后释放本次追踪资源。若将输出重定向成文件,后续保存周期应由诊断流程决定,避免无限积累可能带有程序结构信息的结果。

用 interval 取栈能代替 profile 吗?

不能直接替代。interval 按间隔在一个 CPU 上触发,适合周期动作;profile 面向每 CPU 采样。把 interval 的当前上下文栈当作全进程 CPU 采样,会改变数据来源。

计数很大,就表示函数调用次数多吗?

这里统计的是采样命中次数。一次长时间运行的调用可能被多次采样,很多很短调用也可能没有命中,两者没有一一对应关系。

十秒窗口足够定位所有热点吗?

不保证。窗口需要覆盖有代表性的负载,低频任务可能未出现;先判断样本是否代表要研究的工作,再讨论延长窗口,而不是把缺少样本当成没有问题。

参考资料:profile 探针语法、ustack 与聚合辅助函数、命令行与退出时映射输出。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
ip netns identify 怎么确认进程属于哪个网络命名空间ip netns identify 怎么确认进程属于哪个网络命名空间
上一篇
ip netns identify 怎么确认进程属于哪个网络命名空间
tcpdump -D 怎么列出可用抓包接口并避免选错网卡
下一篇
tcpdump -D 怎么列出可用抓包接口并避免选错网卡
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    893次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    896次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    981次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    968次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    794次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码