使用kdump内核调试工具遇到的问题及解决
修改linux内核代码或者内核模块的时候,搞不好就会造成linux死机崩溃,crash死机后/var/log/kern.log里面不会有任何异常信息记录。这时候kdump就会派上用场了,网上kdump的中英文介绍资料很多,但是很多都是基于系统自带的linux进行说明的,这里记录一下在新编译的内核上使用kdump遇到的问题
1、首先使用ubuntu的config文件编译的内核可以使用kdump
2、在上面的config文件后打开内核编译的DEBUG_INFO选项,编译安装内核后,结果kdmup不起作用,crash后电脑直接卡死没反应,有下面几个现象
通过service --status-all查看,kdump服务成功启动
通过kdump-config show 查看,kdump not ready。
重新启动kdump服务。提示启动成功,但是查看/var/log/syslog,看到有提示"Could not find a free area of memory of xxxxx",kdump预留内存不足,通过/proc/iomem查看已经预留了crash memory,但是预留的crash memory与syslog中提示的内存非常接近
重新启动笔记本,在grub命令行编辑启动命令,设置crash memory为256M,之前grub配置文件中为128M,重启后,发现kdump服务ok,通过kdump-config show查看kdump 也是ready状态。
通过echo c > /proc/sysrq-trigger触发内核崩溃,看到kdump有响应,但是并不会重启笔记本,也不会记录crash信息
3、既然没有配置DEBUG_INFO时候编译的内核可以kdump,配置DEBUG_INFO后编译的内核反而不能kdump,那么在安装尝试把DEBUG信息去掉
objcopy --strip-debug ./vmlinux.o (建议先备份vmlinux.o)
make modules_installs INSTALL_MOD_STRIP=1 install
上面两条命令一个是把内核中的debug信息去掉,另外一个命令则是在安装内核模块的时候,同样把内核模块的debug info去掉,INSTALL_MOD_STRIP这个参数实际上就是从内核makefile中找到的,INSTALL_MOD_STRIP在makefile中就是控制strip-debug是否使能的。
4、经过上面把内核以及内核模块的调试信息去掉后,确认kdump可以正常使用了
root@Inspiron:/home/lybxin# crash doc/ubuntu-compile/vmlinux /var/crash/201610291718/dump.201610291718crash 7.1.4Copyright(C)2002-2015 RedHat,Inc.Copyright(C)2004,2005,2006,2010 IBM CorporationCopyright(C)1999-2006 Hewlett-PackardCoCopyright(C)2005,2006,2011,2012 FujitsuLimitedCopyright(C)2006,2007 VA LinuxSystemsJapan K.K.Copyright(C)2005,2011 NEC CorporationCopyright(C)1999,2002,2007 SiliconGraphics,Inc.Copyright(C)1999,2000,2001,2002 MissionCriticalLinux,Inc.This program is free software, covered by the GNU GeneralPublicLicense,and you are welcome to change it and/or distribute copies of it undercertain conditions. Enter"help copying" to see the conditions.This program has absolutely no warranty. Enter"help warranty"for details.GNU gdb (GDB)7.6Copyright(C)2013FreeSoftwareFoundation,Inc.LicenseGPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type"show copying"and "show warranty"for details.This GDB was configured as "x86_64-unknown-linux-gnu"...KERNEL: doc/ubuntu-compile/vmlinuxDUMPFILE:/var/crash/201610291718/dump.201610291718 [PARTIAL DUMP]CPUS:4DATE:SatOct2917:17:442016UPTIME:00:03:39LOAD AVERAGE:0.69,1.06,0.50TASKS:582NODENAME:InspironRELEASE:4.4.13+VERSION:#35 SMP Fri Oct 28 23:13:30 CST 2016MACHINE: x86_64 (2526Mhz)MEMORY:3.9 GBPANIC:"sysrq: SysRq : Trigger a crash"PID:2656COMMAND:"bash"TASK: ffff880081543e80 [THREAD_INFO: ffff880124db8000]CPU:0STATE: TASK_RUNNING (SYSRQ)crash> btPID:2656 TASK: ffff880081543e80 CPU:0 COMMAND:"bash"#0 [ffff880124dbbaf0] machine_kexec at ffffffff8105ae6b#1 [ffff880124dbbb50] crash_kexec at ffffffff8110cb12#2 [ffff880124dbbc20] oops_end at ffffffff81030c29#3 [ffff880124dbbc48] no_context at ffffffff81069c35#4 [ffff880124dbbca8] __bad_area_nosemaphore at ffffffff81069f00#5 [ffff880124dbbcf0] bad_area at ffffffff8106a0d3#6 [ffff880124dbbd18] __do_page_fault at ffffffff8106a5eb#7 [ffff880124dbbd70] do_page_fault at ffffffff8106a6b2#8 [ffff880124dbbd90] page_fault at ffffffff81832178[exception RIP: sysrq_handle_crash+22]RIP: ffffffff814f42b6 RSP: ffff880124dbbe48 RFLAGS:00010282RAX:000000000000000f RBX:0000000000000063 RCX:0000000000000000RDX:0000000000000000 RSI: ffff880137c0dc78 RDI:0000000000000063RBP: ffff880124dbbe48 R8:0000000000000002 R9:00000000000003edR10:0000000000000001 R11:00000000000003ed R12:0000000000000004R13:0000000000000000 R14: ffffffff81ebada0 R15:0000000000000000ORIG_RAX: ffffffffffffffff CS:0010 SS:0018#9 [ffff880124dbbe50] __handle_sysrq at ffffffff814f4a8a#10 [ffff880124dbbe80] write_sysrq_trigger at ffffffff814f4f0f#11 [ffff880124dbbe98] proc_reg_write at ffffffff81279782#12 [ffff880124dbbeb8] __vfs_write at ffffffff8120b438#13 [ffff880124dbbec8] vfs_write at ffffffff8120bdc9#14 [ffff880124dbbf08] sys_write at ffffffff8120ca85#15 [ffff880124dbbf50] entry_SYSCALL_64_fastpath at ffffffff8182fff2RIP:00007fe506368a10 RSP:00007ffd28c06838 RFLAGS:00000246RAX: ffffffffffffffda RBX:00000000006f4378 RCX:00007fe506368a10RDX:0000000000000002 RSI:00000000011bc408 RDI:0000000000000001RBP:00007ffd28c06770 R8:00007fe506637780 R9:00007fe506c6b700R10:0000000000000001 R11:0000000000000246 R12:00007fe506c6d5d0R13:0000000000000000 R14:00007fe506c8f168 R15:00007ffd28c06798ORIG_RAX:0000000000000001 CS:0033 SS:002b
后记:
实际上编译debug info后遇到两个问题,第一个是预留的crash内存不足的问题,另外一个是预留足够内存后虽然kdump服务正常了,但是内核崩溃的时候仍然不能启动kdump服务
对于第一个预留内存不足的问题,后来查看kdump-tools和kexec-tools的源码,原来kdump-config show执行的时候,就是读取的/sys/kernel/kexec_crash_loaded这个文件的值,如果kexec_crash_loaded为0就表示kdump没有处于ready状态。接着查看内核源码,/sys/kernel/kexec_crash_loaded文件对应内核变量kexec_crash_image,而这个变量只会在两个系统调用中进行修改,一个是kexec_load另外一个是kexec_file_load,而我并没有修改kexec相关的代码,因此内核这块出问题的概率比较小。
通过跟踪kdump服务的启动脚本执行过程,原来启动kdump服务最终执行的命令是/bin/systemctl --no-pager start kdump-tools.service ,而systemctl则会通过/run/systemd/private这个socket与init进程通信,init最终又会执行kexec-tools中的kexec程序,在kexec执行的时候则会查找预留的carsh memory,当预留的内存不足的时候就会输出"Could not find a free area of memory of xxxxx"错误信息,当预留的内存充足的时候,则会执行kexec_load系统调用进行加载。
对于第二个,kdump服务启动后还不能正常使用kdump的问题,打开debug info和debug info对比,发现预留的crash memory位置不同,估计多半和内核的内存机制与kexec机制有关系,这块不太懂了,没有深入研究了。好在单独剥离debug info后可以正常使用kdump。
grub启动文件中crashkernel参数的解析,可以参考内核代码parse_crashkernel
命令备记:
objcopy --only-keep-debug ./vmlinux.o vmlinux.debug
objcopy --strip-debug ./vmlinux.o
INSTALL_MOD_STRIP=1
strace -f -F -ff -o kdump /bin/systemctl --no-pager start kdump-tools.service
linux/boot/vmlinuz-4.4.13 root=UUID=1ba5f5c5-70c3-4936-b757-821899fe6264 ro quiet splash crashkernel=384M-:128M $vt_handoff

浙公网安备 33010602011771号