与 LuaJIT 的漫步

这是一篇关于为 LuaJIT 实现通用零工具BPF性能分析器的记录。

主要观点

  • 介绍为 LuaJIT 实现零工具 BPF 性能分析器的过程。
  • 对比不同性能分析工具(如 perf、LuaJIT 内置分析器等)的优缺点。
  • 阐述 LuaJIT 的特性,如基于跟踪的 JIT、FFI 层等。
  • 详细说明如何通过 eBPF 实现对 LuaJIT 的性能分析,包括获取上下文、处理 JIT 帧等。

关键信息和重要细节

  • Lua 是 90 年代以来的动态通用脚本语言,常用于游戏脚本等,LuaJIT 2005 年由 Mike Pall 发布,其基于跟踪的 JIT 有独特优势但存在“跟踪爆炸”问题。
  • perf 虽能用于 Linux 性能分析,但对 LuaJIT 效果不佳,因其不输出帧指针。
  • Lua 有外部解压器支持用于 C++异常处理,但获取运行时解压器信息较难。
  • LuaJIT 内置分析器因采样技术和 JIT 代码处理问题不适用。
  • GDB 对 JIT 代码的分析有局限性,需借助 LUAJIT_USE_GDBJIT 扩展。
  • LuaJIT 的解释器是用“dynasm”汇编器生成的 C 程序,采用直接线程解释器方式。
  • 实现 eBPF 解压器需确定 LuaJIT 解释器的范围,可通过分析.eh_frame 符号等方式。
  • 对于 JIT 帧,需手动调整栈指针,通过 trace 元数据获取栈帧大小。
  • 在 Lua 中,通过“G”和“L”获取上下文,可利用 uprobes 或特定函数中的指针偏移来实现。
  • 解压器需处理 Lua 调用 native 代码和 C 帧调用回 Lua 的情况。
  • 使用最长前缀匹配尝试(LPM trie)来处理 eBPF 中的地址注册和跟踪垃圾回收。
  • 在用户空间将 PC 和 GCproto 地址转换为函数名等信息。

总结:通过一系列复杂的技术和步骤,实现了对 LuaJIT 的零工具 BPF 性能分析,虽过程曲折但最终取得较好效果。

阅读 21
0 条评论