sysrq l 键触发 show_state() 打印进程状态快照,并非导出任务队列结构体;它显示 r/s/d 状态进程及 cpu 分布,含 cfs_rq/rt_rq 摘要(若启用 config_sched_debug),输出至控制台,需 dmesg 或 syslog 捕获。

什么是 Sysrq 的 l 键 —— 它真能导出任务队列?
不能。Sysrq l(小写 L)触发的是 show_state(),它打印的是当前所有可运行(R)、可中断(S)、不可中断(D)等状态的进程快照,不是“任务队列”的结构体 dump。Linux 内核里没有用户可直接导出的、内存布局完整的“任务队列”对象;show_state() 是最接近的调试入口,但输出是文本摘要,不是原始数据结构。
- 它不输出
struct rq的字段或内存地址,也不展示调度器内部红黑树或 CFS 运行队列细节 - 输出内容依赖当前内核配置:如果禁用了
CONFIG_SCHED_DEBUG,show_state()会跳过部分调度信息 - 输出目标是控制台(
/dev/console或串口),默认不落盘,需配合syslog或dmesg -w捕获
怎么安全触发 Alt+SysRq+l 并捕获输出
安全的关键不是“避免崩溃”,而是“避免干扰当前调度路径”。Sysrq l 本身几乎无副作用,但触发方式不当会导致输入被忽略或误触发其他键:
- 必须在本地物理终端(或真实串口)触发;SSH 会话中
Alt+SysRq组合根本不会传到内核,echo l > /proc/sysrq-trigger可替代,但需 root 权限且绕过键盘校验 - 触发前确认
/proc/sys/kernel/sysrq值为1(或至少包含位掩码0x2,即允许l) - 输出默认刷屏,建议提前运行
dmesg -w &,再触发,然后用Ctrl+C中断并过滤:dmesg | grep -A20 -B5 "task state" - 若系统已卡死在不可中断状态(如
D状态进程占满),l仍可工作——它是通过 NMI 或高优先级中断处理的
show_state() 输出里哪些字段真正反映“运行时队列”状态
输出中没有“任务队列”标题,但以下几行是调度器视角的关键线索:
-
runnable tasks:后面列出的所有R状态进程,就是当前 CPU 的rq->cfs.rq和rq->rt.rt_nr_running中待调度的候选者 - 每行开头的
pid、comm、state、flags、cpu字段,对应struct task_struct的实时值,其中cpu表明该 task 当前绑定/最后运行的 CPU - 若启用
CONFIG_SCHED_DEBUG,还会出现cfs_rq和rt_rq摘要,例如cfs_rq[0]:/ nr_spread_over: 0,这才是 CFS 队列层面的轻量统计 - 注意:
show_state()不区分“就绪”和“正在运行”,R状态包含两者;真正的“运行中”只能靠ps -eo pid,comm,state,psr对比确认
为什么别指望用 Sysrq 导出完整队列结构体
因为内核从不提供这种接口。Sysrq 是调试辅助机制,不是数据导出协议:
-
show_state()是只读、不可配置的文本打印函数,无法指定输出格式、深度或目标缓冲区 - 想看
struct rq字段(如nr_running,clock,cfs.hi_load),唯一办法是用crash工具分析vmlinux+/proc/kcore,或用perf probe动态跟踪,但这些都不属于 Sysrq 范畴 - 生产环境开启
CONFIG_SCHED_DEBUG有轻微性能开销(主要是额外计数和条件判断),而 Sysrql本身无开销,但频繁触发会影响控制台 I/O - 容器环境下,
show_state()显示的是宿主机全局视图,无法隔离到某个 cgroup 的子队列
真正需要队列结构细节时,得切到 crash 或 kgdb;Sysrq l 只适合快速确认“有没有大量 D/R 进程堆积”这类定性判断。











