在使用BCC
之前,先了解一下当前Linux
常用的跟踪技术。有很多技术可以来观察和跟踪,了解观察的边界和跟踪的能力有助于节省时间和克服挫败感。
下面是一些用来对分析技术和工具分类的术语:
BCC
使用这种方式Perf
使用这种方式GDB
提供代码执行的可视化能力这张图实质上是对Linux跟踪的总体了解。需要注意的是,这并不是所有内容的完整列表,也不是每个跟踪前端都使用每个数据提取程序或数据源。
这系列不会详细介绍上图中的所有内容。相反,我们将重点介绍数据源,更具体地说,就是kProbe/kretProbe
、uProbe/uretProbe
、内核跟踪点和USDT Probe
。了解不同的数据源及其功能是了解跟踪前端功能的关键。例如,sysdigg
不使用列出的任何数据源,并且只对系统调用可见。
值得一提的是BCC
与上图的关系。以前所述,BCC
是一个跟踪前端。跟踪前端是一个提供跟踪技术和功能的应用程序, 有时候还会像Perf
一样提供采样。
追踪前端分为两类:底层前端和上层前端。上层前端通常是一种更加用户友好的跟踪工具套件,您可以使用它来快速观察目标。一些上层跟踪前端构建在底层前端之上,例如bpftrace
基于BCC
。底层跟踪前端通常比较简单,用户不太友好,开发人员需要做更多的工作才能充分利用它们。底层前端的好处是您可以更灵活地控制事件、数据处理和显示(尽管DTrace
和bpftrace
也可以提供一些这种灵活性和控制)。
BCC
被认为是一种底层跟踪前端,因为我们需要写脚本去调用它。换句话说,没有像Dtrace
或bpftrace
之类的命令使用,我们需要使用自己的脚本。
BCC
全称是BPF
编译器集合。在上图的BPF
数据抽取器就是BPF
。BPF
为内核(通过kprobes/kretprobes
,内核跟踪点)和用户态(通过uprobes/uretprobes
,USDT probes
)提供了可视化, 使得BCC
变成一个完整灵活的前端。
我们接着要看的数据源是kprobes/kretprobes
,内核跟踪点,uprobes/uretprobes
和USDT probes
。它们非常强大,同时根据它们静态和动态的能力分类。kprobes/kretprobes
和uprobes/uretprobes
是动态跟踪技术,而内核跟踪点和USDT probes
是静态跟踪技术。
动态跟踪 - 可以在运行的进程实时挂钩
kprobes/kretprobes
:对内核函数动态挂钩kprobes
当被挂钩的内核函数开始执行时触发kretprobes
当被挂钩的内核函数返回时触发uprobes/uretprobes
- 对用户态的C
函数实时挂钩uprobes
当被挂钩的用户态C
函数开始执行时触发uretprobes
当被挂钩的用户态C
函数返回时触发API
变动了,需要重新找到相应符号,对内联函数无法跟踪静态跟踪 - 在软件预先定义的跟踪点挂钩
Linux
机器的内核跟踪点可以在/sys/kernel/debug/tracing/events
查看include/trace/events
USDT probes
也叫用户静态定义跟踪点,也是代码预先定义。比如glibc
的__malloc_hook
,__free_hook
。systemtap-sdt-dev
的头文件和工具或自定义的头文件加入到应用程序Linux
跟踪的总结有几种跟踪技术都可以和许多跟踪前端交互,最强大的莫过于kprobes/kretprobes
,uprobes/uretprobes
,内核跟踪点和用户态跟踪点。有一个同时使用静态和动态技术的跟踪前端,是用于观察系统的最佳选择。
记着:kprobes
和uprobes
都是动态挂钩的,这意味着只要在生产环境有它们,只要打开并挂上相应函数就行了,这种方式的好处是零开销,劣势是对不同版本的软件,需要重新找到挂钩的函数。
而静态跟踪可以静态挂钩,意味着它们需要由开发者定义和实现。好处是就是接口稳定,对跟踪的数据类型可以很精准。不好的地方,增减跟踪点需要重新编译,这样会提高代码维护成本。
一个通用的建议是:先用静态跟踪,再用动态跟踪。
暗号:7e46c