Linux死锁检测与排障实战_从Lockdep到ftrace与crash面向内核与系统排障的 Linux 死锁实战指南先讲死锁成立条件与锁语义再给开发期与线上期的工具选型、最小排障路径、典型案例和预防规范目标是“能定位、能复现、能预防”。目录什么是 Linux 死锁内核常见锁与死锁风险点工具选型决策表先看这个开发期Lockdep 预防性检测线上期从现象到根因的排障路径ftrace / gdb / pstack 的定位方法最小复现思路用户态与内核态生产环境补充kdump 与 crash 离线分析预防优先锁层级与编码规范案例复盘模板一页纸排障速查图值班版附录A常见死锁/卡死日志速查附录B用户态 vs 内核态死锁差异常见误区免责声明什么是 Linux 死锁死锁通常指多个执行体互相等待对方持有的资源且在无外力介入下无法推进。成立通常需同时满足四个条件条件说明互斥资源同一时刻仅允许一个持有者请求并保持持有已有资源同时请求新资源不可剥夺资源不能被强制回收循环等待存在环状等待链Thread A 持有 Lock1 等 Lock2Thread B 持有 Lock2 等 Lock1内核常见锁与死锁风险点锁类型场景风险spinlock短临界区、不可睡眠路径锁顺序错误导致忙等互卡mutex可睡眠路径、长临界区ABBA 顺序导致阻塞死锁rwlock/rwsem读多写少升级/降级与写锁争用复杂高风险场景中断上下文与进程上下文争抢同一锁不同子系统对同一资源采用不一致加锁顺序低内存与回收路径叠加锁竞争工具选型决策表先看这个场景首选工具目标预期输出/现象开发阶段、预防潜在死锁Lockdep检测锁依赖环提前报警INFO: possible circular locking dependency detected线上“卡住但还活着”top/ps/lslocksftrace找阻塞点与时序STAT中D增多、锁等待路径可复现用户态多线程互锁gdb/pstack看线程栈和等待关系多线程长期卡在pthread_mutex_lock系统已基本挂死kdump crash离线分析内核转储vmcore 中可见阻塞任务栈与锁持有关系开发期Lockdep 预防性检测Lockdep 通过锁依赖图检测“可能形成环”的加锁顺序。常见内核配置按版本与发行版调整CONFIG_PROVE_LOCKINGCONFIG_LOCKDEP工作方式简化记录“先拿 A 再拿 B”依赖边新增边若形成环输出警告在“死锁真正发生前”暴露风险Lockdep 典型日志简化示意[ INFO: possible circular locking dependency detected ] CPU0 CPU1 lock(A) lock(B) lock(B) lock(A) - deadlock potential如何读possible circular潜在循环等待不代表此刻已完全死锁CPU0/CPU1展示两条并发路径A - B与B - A锁顺序反转ABBALockdep 的边界与局限调试开销较高不建议线上长期全量开启某些复杂上下文中断/软中断交错可能出现难以解读的告警它擅长发现“锁顺序问题”对非锁资源循环等待需结合其它证据线上期从现象到根因的排障路径D 多R 高且CPU高Z 多告警: load高/服务无响应ps/top 定位异常进程状态类型查 I/O 与锁等待点查热点与自旋竞争查父进程回收ftrace/日志还原锁时序修复wait逻辑确认循环等待/锁顺序问题基础命令topps-eopid,ppid,stat,comm,wchan--sortstat lslocksdmesg|rg-ilock|deadlock|hungftrace / gdb / pstack 的定位方法ftrace内核时序追函数进入/退出与延迟还原“谁先拿锁、谁后等待”最小命令流示例cd/sys/kernel/debug/tracingecho0tracing_onechofunction_graphcurrent_tracerechomutex_*set_graph_functionecho1tracing_on# 触发问题路径...echo0tracing_oncattrace/tmp/trace.txt关注点同一把锁是否被反序获取某线程是否长时间停在锁相关函数gdb / pstack用户态线程info threads看线程列表thread apply all bt看全线程栈多次抓栈对比“长期卡在同一锁函数”lslocks输出怎么读字段作用PID/COMMAND谁持有或等待锁TYPE锁类型如 POSIX/FLOCKMODE读锁/写锁READ/WRITEPATH锁关联文件路径最小复现思路用户态与内核态用户态 ABBA 复现线程 A先锁L1再锁L2线程 B先锁L2再锁L1运行并用gdb/pstack捕捉栈可直接编译的最小示例#includepthread.h#includestdio.h#includeunistd.hstaticpthread_mutex_tm1PTHREAD_MUTEX_INITIALIZER;staticpthread_mutex_tm2PTHREAD_MUTEX_INITIALIZER;void*t1(void*arg){pthread_mutex_lock(m1);usleep(100000);pthread_mutex_lock(m2);returnNULL;}void*t2(void*arg){pthread_mutex_lock(m2);usleep(100000);pthread_mutex_lock(m1);returnNULL;}intmain(void){pthread_ta,b;pthread_create(a,NULL,t1,NULL);pthread_create(b,NULL,t2,NULL);pthread_join(a,NULL);pthread_join(b,NULL);return0;}gcc-O0-gdeadlock_abba.c-lpthread-odeadlock_abba ./deadlock_abbapstack$!内核态复现测试环境准备测试模块构造两条路径反序加锁开启 Lockdep触发路径并分析 lockdep 报告简化伪代码spin_lock(A);/* path 1 */spin_lock(B);spin_lock(B);/* path 2 */spin_lock(A);仅建议在测试内核与隔离环境操作。生产环境补充kdump 与 crash 离线分析当系统几乎不可交互时可用 kdump 捕获 vmcore再用crash离线分析步骤目的启用 kdump故障时保留内核现场获取 vmcore保留死锁现场上下文crash分析任务与栈还原等待链与锁持有关系这是“最后一道证据链”。crash常用命令速查ps -u # 看任务状态含不可中断任务 bt pid # 指定任务栈回溯 foreach bt # 批量看栈慎用输出大 log # 查看内核日志缓冲实践提醒线上机器需提前预留crashkernel内存否则故障时可能抓不到 vmcore。预防优先锁层级与编码规范建议把以下规则写入团队规范全局锁顺序表Lock Hierarchy严格按层级拿锁短临界区原则减少持锁时长可中断/超时策略对非关键路径使用 try/timed lock代码评审必查项是否出现 ABBA、是否跨上下文复用锁持续集成检查调试内核定期跑 lockdep 覆盖锁层级示例示意L1: global_lock L2: inode_lock L3: dentry_lock 规则只能从 L1 - L2 - L3 方向获取禁止逆序。try-lock 回退示例用户态if(pthread_mutex_trylock(m2)!0){pthread_mutex_unlock(m1);/* 退避重试或走降级路径 */}案例复盘模板维度记录内容现象负载、告警、业务影响范围证据日志、栈、ftrace、vmcore根因锁顺序、上下文冲突、资源路径修复锁顺序统一、超时回退、流程重构预防规范、测试、监控项与阈值一页纸排障速查图值班版D 多R 高且CPU高Z 多系统几乎挂死服务无响应 / load异常第一步: top ps状态主因?iostat/vmstat /proc//wchanpidstat/perf 看热点pstree waitpid 回收链路kdump crashftrace 追锁时序修复父进程回收逻辑离线栈回溯定位锁环确认锁顺序/资源环回归测试 防回归监控值班执行口诀文字版先定性R / D / Z谁异常最多。再取证栈、等待点、锁持有关系必须成链。后修复统一锁顺序补超时/回退与监控。最后固化把本次根因写入锁层级规范与测试用例。附录A常见死锁/卡死日志速查报错片段示意典型来源含义possible circular locking dependency detectedLockdep潜在锁顺序环task ... blocked for more than 120 secondshung task detector任务长期阻塞BUG: soft lockupwatchdogCPU 长时间未调度hard LOCKUPNMI watchdog更严重的 CPU 卡死迹象附录B用户态 vs 内核态死锁差异维度用户态死锁内核态死锁常用工具gdb/pstacklockdep / ftrace / crash可恢复性往往可重启进程恢复可能影响整机稳定证据采集线程栈 日志内核栈 trace vmcore处理优先级服务级系统级更高常见误区误区修正只靠日志就能定位死锁死锁定位通常必须结合栈与时序kill -9能解所有卡死内核态等待与死锁常不能直接“杀掉”解决Lockdep 线上常开更安全Lockdep 有开销通常开发/测试内核使用只修一次锁顺序就完事需建立长期锁层级规范与回归测试免责声明工具与内核配置项会随发行版和内核版本变化具体以现场环境与官方文档为准。文中流程用于工程排障框架不替代你所在系统的安全与运维规范。