linux 内核调试

1. 背景

linux 内核是介于应用和驱动之间的抽象层;系统调用api是kernel与app间的接口,kernel与driver之间也有一层low-level-api(如注册驱动模块,注册中断ISR等),driver与设备间的接口即为I/O寄存器(寄存器地址与硬件配置有关)。内核的主要任务是满足多个应用对设备资源(CPU、RAM、DISK、NET)的请求,而实际的硬件资源是有限的,不同需求的应用无限,如何合理分配资源是kernel的主要设计问题。


2. 遇到的问题

a)应用调用的api执行结果是否有效?

b)应用调用的api响应时间是否够快?

c)kernelspace的代码出现非法内存地址访问;

d)kernelspace的线程出现死锁,无响应;

e)kernelspace出现内存泄漏


3. 可行的解决方案

a)理解kernel的运行上下文:

启动流程> startkernel -> deviceinit (requestirq) -> registerfilesystem -> mountrootfs -> /sbin/init -> /bin/bash

请求等待> scanf -> read -> inode-lookup -> fs_read -> readblock -> wait-dma -> sleep -> schedule

响应唤醒> disk-irq -> dma-done -> wakeup -> schedule -> readblock -> fs_read -> read

b) kernel中的全局变量因多线程(不同应用进程的系统调用或中断请求)访问需要加锁;

函数中引用到了全局变量的需要在引用处加锁或该函数被引用时加锁;mutex和spinlock都不可重复获取;

c) 跟踪api的执行结果和时间:printk日志(/proc/kmesg),dumpstack检查调用顺序,  strace 和 ftrace的使用

d)kernel异常操作出现panic或oops时:使用addr2line vmlinux 0x2121241 检查出错的源码行和调用栈;

e)对于kernel中出现的卡死问题,打开CONFIG_DETECT_HUNG_TASK,可用echo w > /proc/sysrq-trigger打印阻塞线程调用栈,然后分析各线程持有的交叉锁;

f)使用kexec转存kernel crash时的内存镜像vmcore,待重启后使用crash工具分析;对于锁死问题可强制触发crash:echo c >/proc/sysrq-trigger, 再转存内存日志分析;

g)对于内存泄漏问题可打开相关内存检查config:CONFIG_DEBUG_KMEMLEAK、 CONFIG_KMEMCHECK,然后从日志输出中定位泄漏代码行;


 4. 参考链接

a)Linux内核调试方法总结

b)Linux kernel 加Memory leaker 检查

c)Linux 内核内存检测工具 - Kmemcheck

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值