解开一个揭示 Arm64 JIT 编译器错误的 Postgres 段错误 | Datadog

主要观点:团队在 Postgres 服务器日志中发现“server process was terminated by signal 11: Segmentation fault”错误,经调查发现是 Postgres JIT 编译中的 LLVM 问题导致 Arm64 架构的集群崩溃,通过深入调试和研究,最终找到根本原因并在上游 Postgres 中发布修复方案。
关键信息:

  • 新部署的 Postgres-on-Kubernetes 平台上的集群出现崩溃,通过排查排除硬件问题,发现是特定查询模式触发的段错误。
  • 深入研究 JIT 编译,发现是 LLVM 中 Arm64 架构的一个 bug,导致在执行“query of death”时出现无限循环和段错误等症状。
  • 通过在调试环境中复制问题,确定是生产集群运行在 Arm64 云实例上与测试环境的差异导致,且在调试过程中发现 JIT 代码生成和汇编中的问题。
  • 进一步研究 LLVM 的地址重定位机制,发现由于 Arm64 ABI 要求与 JIT 代码的内存分配冲突,导致生成错误的机器代码。
  • 最终在 upstream Postgres 中发布修复方案,通过提供自定义的SectionMemoryManager来解决问题,提高了 Postgres 在 Arm64 上的可靠性。
    重要细节:
  • 展示了多个相关人员的图片,包括 Anthonin Bonnefoy、Mitch Ward 和 Gillian McGarvey。
  • 详细描述了调查过程中的各个步骤,如隔离问题、JIT 原理、在调试环境中测试、发现无限循环、找到生成汇编的代码、研究 Arm64 中的 switch 语句实现、发现 LLVM 断言以及 JIT 代码段分配与 Arm64 ABI 要求的冲突等。
  • 提及了相关的 GitHub 问题和 PR,以及与其他使用 LLVM JIT 的项目的关联。
  • 介绍了在 Postgres 社区中讨论和解决问题的过程,以及最终发布修复版本的情况。
阅读 10
0 条评论