LinuxBPF学习笔记 - 堆栈跟踪[3]
Posted 宣之于口
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LinuxBPF学习笔记 - 堆栈跟踪[3]相关的知识,希望对你有一定的参考价值。
一、简介
堆栈跟踪,也称为堆栈回溯跟踪或调用跟踪,是显示代码流的一系列函数. 堆栈跟踪可以用于了解导致事件的代码路径, 以及对内核和用户代码进行性能分析(profiling)以观察执行时间.
举例说明:
func_c() # 当前函数
func_b()
func_a() # 堆栈的底部
二、堆栈遍历
BPF提供了用于记录堆栈跟踪的特殊映射类型,并且可以使用基于帧指针或基于ORC的堆栈遍历来获取它们
1. 基于帧指针
对于 x86-64 架构,共有16个64位通用寄存器。其中%RPB
是栈帧指针,用于标识当前栈帧的起始位置(栈底)。
帧指针技术遵循的惯例是: 始终可以在寄存器 x86_64 上的%RBP
中找到栈帧的起始位置,并且将返回地址存储在与所存储RBP的已知偏移量(+8)处。 这意味着,任何中断程序的调试器或跟踪器都可以读取%RBP
,然后通过遍历%RBP
链表并以已知的偏移量获取地址来轻松获取堆栈跟踪. [TODO: 这部分内容暂未理解, 待补充, 详见原文 P101]
三、火焰图
堆栈跟踪的定时采样可以收集成千上万个堆栈,每个堆栈可以长达数十或数百行。
Linux perf profiler
将其总结为调用树,显示每个路径的百分比BCC profile
计算每个堆栈(唯一)的出现次数
首先我们考虑以下示例: 由输出可见, 代码路径func_a() -> func_b() -> func_c()
出现了7次
func_e
func_d
func_b
func_a
1
func_b
func_a
2
func_c
func_b
func_a
7
1. 基本概念
火焰图是基于上述结果产生的SVG 图片,可以用来展示 CPU 的调用栈. 其具有以下特性:
- 每个框代表堆栈中的一个方法(栈桢), 最上面的框为正在运行的方法
- y轴显示堆栈深度(堆栈中的帧数)
- x轴没有像大多数图形一样显示从左到右的时间流逝, 从左到右的顺序是按字母顺序排序的帧,以最大程度地合并帧; 宽度代表了调用栈在全局出现的次数,次数代表着出现频率
由于这是显示CPU样本的火焰图,进一步分析可以得到:
- 我们最主要的关注点要放在方块的宽度上:
func_c
:70%,func_b
: 20%,func_c
: 10%.func_a
和func_d
未直接在CPU上采样 - 观察火焰图底部或中部方块的宽度占比意义不大, 例如
func_a
函数宽度为100%, 但真正消耗时间的它的子调用是func_c
- 我们更应该关注的是火焰图顶部的一些 平顶山,顶部说明它没有子调用,方块宽说明它耗时长。
2. 生成火焰图
我们通过点击和鼠标指向可以展示出更多的信息。下图就是一个典型的火焰图,从结构上,它是由多个大小和颜色各异的方块构成,每个方块上都有字符,它们底部连接在一块,组成火焰的基底,顶部分出许多“小火苗”
# 生成脚本文件
[root@rumia ~] perf script -i perf.data &> perf.unfold
# 执行完成后生成perf.svg图片,可以下载到本地,用浏览器打开 perf.svg
[root@rumia ~] ./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
[root@rumia ~] ./FlameGraph/flamegraph.pl perf.folded > perf.svg
3. IDEA 结合火焰图
使用前注意Idea版本, 具体不太清楚哪个版本, 最新的肯定是可以~
a. 开启火焰图
- 按下快捷键
shift alt command + /
- 选择
4 Experimental features
- 勾选
idea.profiler.enbaled
b. 运行
示例代码:
public static void main(String[] args)
Map map = new HashMap();
for (int i = 0; i < 10; i++)
byte[] b = new byte[1024*1024];
map.put(i,b);
System.out.println(map);
-
选择
CPU Profiler
执行程序, 然后就可以查看堆栈火焰图 -
选择
Allocation Profiler
执行程序, 然后就可以查看堆分配火焰图: 此处调用堆栈的宽度与堆内存分配量成正比. 最顶部的调用堆栈元素代表分配的数据类型,即数组(byte [])或对象(StandardFilter)
以上是关于LinuxBPF学习笔记 - 堆栈跟踪[3]的主要内容,如果未能解决你的问题,请参考以下文章