如何调试死锁的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




