Hacker News 中文摘要

RSS订阅

内核漏洞导致机器冻结:调试异步分析器死锁问题 -- A kernel bug froze my machine: Debugging an async-profiler deadlock

文章摘要

文章讲述了作者在使用async-profiler工具调试QuestDB数据库性能时,意外触发了Linux内核的一个bug导致机器冻结。尽管作者并非内核开发者,但仍深入研究了内核源代码以定位问题根源。这反映了开源数据库QuestDB在性能优化过程中遇到的技术挑战,以及开发者对问题追根究底的态度。

文章总结

内核漏洞导致机器冻结:调试Async-profiler死锁问题

问题背景

作者在使用Linux系统时,发现每当运行async-profiler工具时,机器会完全冻结。该问题出现在Ubuntu 25.10和Fedora系统中,均使用6.17版本的内核。经过排查,确认这是一个内核漏洞,与perf_events子系统的hrtimer处理有关。

问题复现与定位

  1. 现象:当尝试使用async-profiler进行CPU性能分析时,机器无响应,只能强制重启。
  2. 排查过程
    • 排除QuestDB集成代码的问题,确认问题与环境相关。
    • 发现Ubuntu 25.10和Fedora均使用6.17内核,且旧版本系统无此问题。
    • 通过Google搜索,找到类似问题的报告,并定位到相关内核补丁。

内核漏洞分析

  1. 根本原因:内核提交18dbcbfabfff修复了另一个漏洞,但引入了cpu-clock事件处理的死锁问题。
    • PERF_EVENT_IOC_REFRESH(1)计数器归零时,hrtimer_cancel()在回调函数内部被调用,导致无限等待。
  2. 死锁流程
    • hrtimer触发perf_swevent_hrtimer()
    • __perf_event_overflow()决定停止事件,调用cpu_clock_event_stop()
    • cpu_clock_event_stop()调用hrtimer_cancel(),而当前正在执行回调函数,导致死锁。

解决方案

  1. 临时规避:使用-e ctimer选项启动async-profiler,避免触发有问题的内核功能。
  2. 内核修复
    • hrtimer_cancel()替换为非阻塞的hrtimer_try_to_cancel()
    • 使用PERF_HES_STOPPED标志作为延迟停止信号,确保定时器最终停止。

内核调试实践

作者通过QEMU模拟环境复现问题,并利用GDB调试内核: 1. 环境搭建:在QEMU中安装Ubuntu 25.10,并禁用KASLR以方便调试。 2. 调试过程: - 使用GDB连接QEMU的内核调试服务器,查看死锁时的线程堆栈。 - 确认hrtimer_cancel()在回调函数内部被调用,导致死锁。 3. 尝试修复:通过GDB强制修改寄存器值,试图解除死锁,但未完全成功。

结论与建议

  1. 用户建议:在6.17内核版本中,使用-e ctimer选项进行性能分析,或等待内核修复。
  2. 技术收获:作者通过本次调试深入理解了Linux内核的perf_events和hrtimer机制,并掌握了内核调试的基本方法。

后续尝试

在后续实验中,作者通过GDB直接修改内核内存,强制终止Java进程并解除死锁,成功恢复了系统响应。尽管这种方法不适用于生产环境,但为理解内核行为提供了宝贵经验。


:本文保留了关键的技术细节和调试过程,删减了部分实验失败的冗余描述,突出了问题定位和解决的主线。

评论总结

以下是评论内容的总结:

  1. 作者自述
    作者表示对内核感兴趣但无实际经验,认为本文是了解内核内部的一种实践方式。
    引用:
    "Consider this either a collection of impractical party tricks or a hands-on way to get a feel for kernel internals."
    "我一直对内核感到好奇,尽管从未亲自参与过相关工作。"

  2. 技术分享与推荐
    有评论推荐了async-profiler的热图功能及Netflix相关技术博客,认为这些工具能帮助发现时间模式。
    引用:
    "these heatmaps make it much easier to see patterns over time"
    "热图能更轻松地观察时间模式"

  3. 代码缺陷讨论
    有评论指出代码中运算符优先级可能导致的bug,建议使用括号明确逻辑。
    引用:
    "The bug being that the precedence of || is higher than the precedence of != ?"
    "||的优先级高于!=,这是否是个bug?"

  4. 内核复杂性批评
    有评论认为Linux内核过于复杂,存在许多未发现的bug,推荐seL4作为替代方案。
    引用:
    "with the complexity of the Linux kernel, this is definitely not the only bug"
    "Linux内核如此复杂,这肯定不是唯一的bug"

  5. 实际使用问题
    用户报告在高负载Docker环境下偶发内核死锁问题,但难以复现。
    引用:
    "it leads to a complete deadlock somewhere inside of the kernel"
    "导致内核某处完全死锁"

  6. 工具建议
    有评论建议使用bpftrace进行调试,认为比qemu+gdb更高效。
    引用:
    "That would be less effort than qemu + gdb"
    "这比qemu+gdb省力"

  7. 文章评价
    多位读者称赞文章是优秀的"调试历程"记录,并提到该问题曾导致Minecraft系统冻结。
    引用:
    "This kind of 'debugging journey' post is gold"
    "这种'调试历程'文章很有价值"
    "the bug that froze the system when Minecraft was running"
    "这个bug曾导致运行Minecraft时系统冻结"