You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何调试死锁的rippled?调试构建dogfood机器死锁后GDB断点最优操作

调试死锁的rippled进程:GDB断点触发后的最优下一步操作

碰到rippled死锁确实头疼,既然已经在GDB里挂住进程了,终止前一定要把关键信息都捞到手,按优先级来做这些操作:

  • 先抓全所有线程的完整栈跟踪
    这是分析死锁的核心,执行命令:

    thread apply all bt full
    

    这个命令会输出每个线程的完整调用栈,包括局部变量和函数参数。死锁本质是线程互相等待对方持有的锁,通过栈跟踪你能看到每个线程卡在哪个锁的等待逻辑上,比如是不是卡在std::mutex::lock()或者rippled自定义锁(比如LockedPointer)的获取步骤。

  • 检查线程持有的锁与等待的锁
    结合栈跟踪进一步确认锁状态:

    • info locks命令查看进程中所有被持有的锁(需要完整调试符号支持)
    • 如果rippled调试构建开启了锁调试宏(比如LOCK_DEBUG,通常默认启用),可以查看线程局部存储里的锁持有记录,或者调用rippled内置的调试函数(比如dumpLocks(),若有暴露)输出所有锁的持有者和等待者。
  • 保存core dump留作后续分析
    执行命令生成core dump文件:

    gcore rippled_deadlock.core
    

    这样即使终止进程,之后也能随时加载这个core dump回到当前死锁现场,反复调试分析。复杂死锁一次可能看不全,留个备份绝对没错。

  • 确认线程状态与关键寄存器信息

    • info threads列出所有线程的ID、状态和当前函数,标记出处于waiting状态的线程
    • 切换到可疑线程(比如thread 3),用info registers查看寄存器状态,或者x/10i $pc看当前执行的汇编指令,确认是不是真的卡在锁等待逻辑上,而非其他阻塞场景。

做完这些操作后,再终止进程就不用担心丢失关键调试信息了,接下来可以慢慢分析栈跟踪和core dump,定位死锁根源——比如是不是锁的获取顺序不一致,或者某个锁没有正确释放。

内容的提问来源于stack exchange,提问作者John Freeman

火山引擎 最新活动