使用ebpf的bcc工具对Linux内核和程序进行跟踪2:BCC介绍
2022-12-16 12:41:53 Author: 奶牛安全(查看原文) 阅读量:15 收藏

BCC是第一个基于BPF的上层跟踪框架。BPF是一种在1992年开发用来提高网络包过滤性能的技术。在2003年,它被重写扩展为eBPF,在2014年引入到Linux内核。它的重写使得它变成一个通用的执行引擎,增强它的潜力。

1992年开发的BPF被称为“古典BPF“,已经停止开发,现在eBPF是主流。目前所称的BPF就是指eBPF

这项新技术提供在内核和用户态应用(如磁盘IO,QEMU)等事件上运行小程序的方法。本质上,它让内核更加可编程化,给予内核开发人员或非内核开发人员更多能力去调整和控制系统,直到他们认为适合为止。

intel体系CPU幽灵漏洞后,一些Linux发行版在x86体系无条件开启JIT,完全抛弃掉eBPF字节码解析器。

BPF同时使用了一个验证器来检查BPF指纹是否安全,确保它不会破坏内核。然而,它并不完美,因为它无法阻止用户写出某些非逻辑但可运行的代码。一个隐性的除零错误是没办法被验证器捕获,但一个无限循环,却会被捕获。

为啥需要关注BCC

如果BCC背后的真正动力是BPF,那么BCC到底为我们做了什么?在BCC之前,BPF的唯一前端是原始的BPF字节码、Cperf。虽然这些工具/前端的原始潜力非常高,但要充分利用这些工具/前端的BPF是非常困难的。换句话说,对于大多数人来说,学习曲线太陡峭了,将选择其他跟踪技术(以能力换取简单性)。

BCC保留了BPF的原始潜力,也使大多数开发人员更容易接触到它。它为编写内核BPF C代码(也称为嵌入C)提供了C编程环境,并为用户空间接口提供了PythonLuaC++。换句话说,您可以使用嵌入C从跟踪的事件中提取数据,并使用Python脚本、LuaC++程序以您想要的方式进一步处理和显示数据。使用BCC来开始编写自己的BPF程序的学习曲线大大减少(而且相当直接),特别是现在它已经成熟了,已经发布了多年,有更多的文档,等等。

除了使BPF的潜力更加贴近实际之外,BCC存储库还包含70多个用于性能分析和调试的现成BPF程序。正如您在下图中看到的,堆栈中的几乎所有内容都有一个脚本!这些都是现成的,每个都有完整的文档和示例用法。还有大量的资源甚至指南可以帮助你开始开发你自己的BPF程序。

tools

谁会对BCC感兴趣

一般来说,在跟踪中,编写一个C程序来提取数据并编写一个Python或C++程序来处理和显示数据并不是最快的事情,特别是当您可以在不同的前端使用一行程序来获得相同的结果时(尽管BCC确实有提供这种“一行程序”能力的BPF工具trace.py)。

以下是一些BCC会比其它跟踪前端更有用的理由:

  • 需要一些类似perf的工具,但想在数据收集和展示有更多掌控
  • 需要收集自定义统计数据,监察特定事件
  • 需要对系统/子系统创建定制的分析工具
  • 需要对跟踪事件,数据处理和输出展示有完全控制
  • 需要用BPF
  • 某个BCC工具的功能贴近需求,且希望重构它

从根本来说,当你需要对系统正在发生什么有更深的了解和想对收集的数据有完全把控,BCC是一个不错的选择。

BCC特性

下面列举BCC提供给我们的特性,包括内核级,用户态级和一些自带的工具。

内核特性

BCC使用了一系列内核特性,如BPF,kprobes,uprobes

  • 内核级动态跟踪,kprobes
  • 用户态级动态跟踪,uprobes
  • 内核级静态跟踪,内核跟踪点
  • 计时采样事件,通过perf_event_open
  • 性能监控计数事件,通过perf_event_open
  • 过滤
  • 调试输出bpf_trace_printk
  • 单个事件输出bpf_perf_event_output
  • 基础变量(全局或线程本地变量,通过BPF映射)
  • 关联数组(通过BPF映射)
  • 频率计数(通过BPF映射)
  • 直方图(平方,线性或自定义,通过BPF映射)
  • 时间戳和时间差分(bpf_ktime_get_nsBPF程序)
  • 内核栈跟踪(BPF栈映射)
  • 用户态栈跟踪(BPF栈映射)
  • 覆盖环形缓存(perf_event_attr.write_backward)
  • 低开销操作(BPF JIT,BPF映射总览)
  • 生产安全(BPF校验器)

用户态特性

BCC通过它的用户态前端也提供了一系列用户态特性:

  • 静态跟踪(通过uprobes进行SystemTap风格的跟踪(DTRACE_PROBEn))
  • 调试输出(Python使用BPF.trace_pipeBPF.trace_fields)
  • 单事件输出(BPF_PERF_OUTPUT宏和BPF.open_perf_buffer)
  • 定时输出(BPF.get_tabletable.clear)
  • 内核态C结构数据监测(bpf_probe_read)
  • 内核符号解析(ksymksymaddr)
  • 用户态符号解析(usymaddr)
  • 调试符号解析支持
  • BPF跟踪点支持(TRACEPOINT_PROBE)
  • BPF栈跟踪支持(BPF_STACK_TRACE)

其它特性

除了 BCC 必须提供的所有技术功能外,它还附带了大量示例、教程和自带工具。

BCC中包含两个教程:使用 BCC 工具解决性能、故障排除和网络问题的教程,以及 BCC BPF Python 开发人员教程,让您开始使用 C 和 Python 编写自己的 BPF 程序。

  • docs/tutorial.md:使用 BCC 工具解决性能、故障排除和网络问题的教程
  • docs/tutorial_bcc_python_developer.md:使用 Python 接口开发新的 BCC BPF 程序

examples/* 中的 BPF 程序对应 BCC Python 开发者教程;这些仅供参考

BCC 附带的自带 BPF 工具可以在 tools/* 中找到,而且数量很多!每个工具都带有自己的 *.txt 文件,作为该工具的手册页。其中一些工具包括:

  • tools/biolatency.py/txt:将块设备 I/O 延迟总结为直方图
  • tools/cpuunclaimed.py/txt:样本CPU运行队列并计算出空闲CPU
  • tools/hardirqs.py/txt:测量hard IRQ(硬中断)事件时间
  • tools/klockstat.py/txt:跟踪内核互斥锁定事件并显示锁定统计信息
  • ...

可以在BCC GitHub存储库 (README.md) 的首页找到这些自带工具的完整列表。

最后,还有BCC参考指南。应该注意的是,可能无法在此处找到所有内容,并且缺少一些 API(即 bpf_usdt_readarg)。但是,此处列出了需要的大部分内容,如果没有明确说明,可以在自带工具和示例中找到示例用法,以帮助解决问题。

  • docs/reference_guide.mdBCC/BPF API 参考指南

暗号:b1117


文章来源: http://mp.weixin.qq.com/s?__biz=MzU4NjY0NTExNA==&mid=2247488117&idx=1&sn=77dc597d0ccad3f145b0169849be7b61&chksm=fdf97960ca8ef0763d625dc09f828f13cfc28304b527861dd22d3aeffc4b76ec58059c2aa25a#rd
如有侵权请联系:admin#unsafe.sh