内核sysrq使用方法
1、SysRq键介绍
SysRq键可以在内核无法登陆,按键无响应时,尚能够响应中断时使用。可以内核卡死的情况下获取内核状态的部分信息,便于进行问题分析。下面介绍串口下使用SysRq键进行内核调试的方法。当内核无法响应,不能登录时,通过串口向内核发送SysRq键命令的方法是:先发送break信号,之后在5s中内发送SysRq键,内核即能做出相应的相应。
2、配置内核响应SysRq键
在内核配置选项中,启用内核配置CONFIG_MAGIC_SYSRQ
$ make menuconfig
Kernel hacking —>
[*] Magic SysRq key
配置以上选项后,编译内核,启动后通过以下命令开启SysRq功能:
echo 1 > /proc/sys/kernel/sysrq
有些内核中默认该功能是启用,只需配置CONFIG_MAGIC_SYSRQ选项即可。
3、SysRq键的输入方法
以SecureCRT为例说明串口下,SysRq间的输入方法。
1. 先通过映射键,映射BREAK键,如下图将Ctrl+Shift+b的组合键映射为BREAK键:
2. 使用时,先按Ctrl+Shift+b组合键,输入BREAK,然后再5s内按下响应的SysRq键即可。
4、SysRq命令键说明
标准内核中支持支持28种不同的命令键,而根据内核版本与Kernel hacking选项中开启的选项不同,具体的内核支持的命令键个数不同,也可以通过自定义的方式扩充或者修改具体SysRq键的功能。通过SysRq的h键可以知道内核中支持的SysRq命令键的详细说明,下面是设备所支持的SysRq命令键:
\~\# SysRq : HELP : loglevel(0-9) reBoot Crash terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) thaw-filesystems(J) saK show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T) Unmount show-blocked-tasks(W)
调试时常用的SysRq键有m,n,p,t,w,其具体功能如下:
m, 输出内存和交换文件的状态
n,强制将所有的实时进程变成普通进程。相当于通过sched_setscheduler(2)将任务调度策略设置为SCHED_NOMAL
p, 输出CPU寄存器和正在运行的进程的信息,多个CPU情况下,只输出处理了键盘终端的CPU信息
t, 调用backtrace,输出所有正在运行的进程的栈
w, 只输出处于UNINTERRUPTABLE的等待状态且忽略各种信号的进程信息
5、使用SysRq命令键定位举例
设备在测试生成core文件时发现,当系统出现段错误时,并不能生成core文件。 而是卡死无响应,直到看门狗超时导致重启。 最后定位到系统卡死在DM648模块中向DSP发送消息的接口中有一个while(1)的处理中。 当时没有SysRq的调试方法,只能通过逐个代码模块屏蔽,然后重新编译运行,逐个排除,整个调试的过程花费了两天时间,涉及到应用、系统、音视频、DSP四个团队。 现在使用SysRq的方法是这去分析定位该问题。
重现该现象,使用SysRq键的方法打印出其卡死之后的内核部分信息。
使用m键,查看系统内存如下:
SysRq : Show Memory
Mem-info:
Normal per-cpu:
CPU 0: hi: 42, btch: 7 usd: 12
active_anon:7821 inactive_anon:1 isolated_anon:0
active_file:2503 inactive_file:9300 isolated_file:0
unevictable:0 dirty:0 writeback:0 unstable:0
free:12436 slab_reclaimable:128 slab_unreclaimable:1017
mapped:1600 shmem:1 pagetables:169 bounce:0
Normal free:49744kB min:1548kB low:1932kB high:2320kB active_anon:31284kB inactive_anon:4kB active_file:10012kB inactive_file:37200kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:150368kB mlocked:0kB dirty:0kB writeback:0kB mapped:6400kB shmem:4kB slab_reclaimable:512kB slab_unreclaimable:4068kB kernel_stack:1032kB pagetables:676kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0
Normal: 2\*4kB 5\*8kB 2\*16kB 2\*32kB 1\*64kB 1\*128kB 1\*256kB 2\*512kB 1\*1024kB 1\*2048kB 11\*4096kB = 49744kB
11804 total pagecache pages
37888 pages of RAM
12604 free pages
1655 reserved pages
940 slab pages
3964 pages shared
0 pages swap cached
由上面信息可知,系统剩余内存充足,不是因为内存不足造成的系统卡死
使用p查看CPU寄存器与正在运行的进程状态如下:
SysRq : Show Regs
Pid: 193, comm: Challenge
CPU: 0 Not tainted (2.6.37 \#23)
PC is at memset+0x58/0xc0
LR is at 0x0
pc : [\<c01d7778\>] lr : [\<00000000\>] psr: 00000113
sp : c463bd64 ip : 00000000 fp : c463bdb4
r10: c463a000 r9 : cbdcb0f4 r8 : 5df56c3c
r7 : cbdcb000 r6 : 00000001 r5 : c4638000 r4 : c463bd7c
r3 : 00000000 r2 : ffffffd4 r1 : 00000000 r0 : c463bd80
Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 84a78019 DAC: 00000015
[\<c00454f4\>] (show_regs+0x0/0x50) from [\<c0207048\>] (sysrq_handle_showregs+0x20/0x28)
r5:00000001 r4:c04ebed0
[\<c0207028\>] (sysrq_handle_showregs+0x0/0x28) from [\<c0206b58\>] (__handle_sysrq+0xac/0x150)
[\<c0206aac\>] (__handle_sysrq+0x0/0x150) from [\<c0206c5c\>] (handle_sysrq+0x28/0x2c)
r9:60000193 r8:00000100 r7:00000070 r6:00000080 r5:00000061
r4:00000070
[\<c0206c34\>] (handle_sysrq+0x0/0x2c) from [\<c021ffb0\>] (serial_omap_irq+0x1e4/0x744)
r5:00000061 r4:c8f00e00
[\<c021fdcc\>] (serial_omap_irq+0x0/0x744) from [\<c00992a8\>] (handle_IRQ_event+0x2c/0xec)
[\<c009927c\>] (handle_IRQ_event+0x0/0xec) from [\<c009b48c\>] (handle_level_irq+0xac/0x11c)
r7:cbdcb000 r6:00000001 r5:00000048 r4:c04df04c
[\<c009b3e0\>] (handle_level_irq+0x0/0x11c) from [\<c003907c\>] (asm_do_IRQ+0x7c/0xa0)
r5:00000000 r4:00000048
[\<c0039000\>] (asm_do_IRQ+0x0/0xa0) from [\<c038d0f4\>] (__irq_svc+0x34/0xa0)
**Exception stack(0xc463bd18 to 0xc463bd60)**
bd00: c463bd80 00000000
bd20: ffffffd4 00000000 c463bd7c c4638000 00000001 cbdcb000 5df56c3c cbdcb0f4
bd40: c463a000 c463bdb4 00000000 c463bd64 00000000 c01d7778 00000113 ffffffff
r5:fa200000 r4:ffffffff
[\<bf133114\>] (send_dsp_msg+0x0/0x1d4 [648mod]) from [\<bf134fdc\>] (process_ioctl+0x114c/0x1184 [648mod])
[\<bf133e90\>] (process_ioctl+0x0/0x1184 [648mod]) from [\<bf132960\>] (dm64x_ioctl+0x14/0x18 [648mod])
[\<bf13294c\>] (dm64x_ioctl+0x0/0x18 [648mod]) from [\<c00d1378\>] (vfs_ioctl+0x28/0x44)
[\<c00d1350\>] (vfs_ioctl+0x0/0x44) from [\<c00d1a88\>] (do_vfs_ioctl+0x500/0x540)
[\<c00d1588\>] (do_vfs_ioctl+0x0/0x540) from [\<c00d1b20\>] (sys_ioctl+0x58/0x7c)
[\<c00d1ac8\>] (sys_ioctl+0x0/0x7c) from [\<c0043e60\>] (ret_fast_syscall+0x0/0x30)
r8:c0044008 r7:00000036 r6:47554244 r5:ffffffff r4:02180824
最后有一段异常栈帧,是关于dm648模块中的send_dsp_msg接口调用。而隔一段时间使用p打印,依然卡住在这个地方,说明系统一直陷入在send_dsp_msg()接口的处理中。通过SysRq可以迅速定位到具体的代码模块中,少去了逐个模块屏蔽的工作量。
7:00000036 r6:47554244 r5:ffffffff r4:02180824
最后有一段异常栈帧,是关于dm648模块中的send_dsp_msg接口调用。而隔一段时间使用p打印,依然卡住在这个地方,说明系统一直陷入在send_dsp_msg()接口的处理中。通过SysRq可以迅速定位到具体的代码模块中,少去了逐个模块屏蔽的工作量。