使用crash工具分析vmcore时如何确定线程的阻塞时长
使用crash工具分析vmcore时线程阻塞时长的确定方法
计算原理
vmcore保存了系统崩溃瞬间的内核态全量信息,线程阻塞时长本质是线程进入阻塞状态的时间到系统崩溃时间的时间差。
具体操作步骤
- 第一步:获取系统崩溃时间戳
执行sys命令,在输出中提取TIMESTAMP字段对应的时间值,记为T_panic,即内核触发panic的精确时间。 - 第二步:获取目标线程的阻塞起始时间
首先从栈信息中提取目标线程的task_struct地址,示例中的线程task地址为ffffa035b3d0a080,执行以下命令查看线程调度信息:
在输出中提取以下两个字段任意一个即可:task -x ffffa035b3d0a080last_run:线程最后一次被切换出CPU的时间,也就是阻塞发生的起始时间,记为T_sleep- 若内核版本支持,可直接提取
sleep_start字段,该值为线程主动进入睡眠等待状态的精确时间,计算结果更准确
- 第三步:计算阻塞时长
直接对两个时间戳做差值计算即可:阻塞时长 = T_panic - T_sleep
示例场景验证
本次示例线程栈信息如下:
PID: 10637 TASK: ffffa035b3d0a080 CPU: 7 COMMAND: "md66_raid10" #0 [ffffa035b2363c08] __schedule at ffffffffb616ab17 #1 [ffffa035b2363c90] schedule at ffffffffb616b019 #2 [ffffa035b2363ca0] percpu_ref_switch_to_atomic_sync at ffffffffb5d7af15 #3 [ffffa035b2363ce8] set_in_sync at ffffffffb5f8d6a7 #4 [ffffa035b2363d10] md_check_recovery at ffffffffb5f95fd7 #5 [ffffa035b2363d30] md_check_recovery at ffffffffb5f96368 #6 [ffffa035b2363d40] raid10d at ffffffffc093bc45 [raid10] #7 [ffffa035b2363e50] md_thread at ffffffffb5f8cc3d #8 [ffffa035b2363ec8] kthread at ffffffffb5ac1f81 #9 [ffffa035b2363f50] ret_from_fork_nospec_begin at ffffffffb6177c1d
该线程栈顶停在percpu_ref_switch_to_atomic_sync函数内的调度逻辑,说明从T_sleep时间点开始,线程就处于等待percpu引用计数器切换至atomic模式的状态,上述方法计算出的时间差就是该线程的实际等待时长。
额外验证技巧
如果是等待mutex、信号量、等待队列等特定同步对象的阻塞场景,还可以通过解析同步对象的元数据辅助验证:
- 提取栈中阻塞函数持有的同步对象地址,执行
struct <同步对象类型> <对象地址>查看对象的等待队列起始时间、持有者信息,和上述方法计算的阻塞时长做交叉验证即可。
内容的提问来源于stack exchange,提问作者feeling_lonely
相关产品推荐
相关产品推荐

