各位工程师在Linux下开发程序时,有没有遇到因为体系中存在某些小毛病而跳出了“Oops”提示的状况,此刻你是怎么排查毛病?一行行的检查代码吗?其实不必那么杂乱,本文将为你介绍一种高效的Linux编程的毛病扫除办法。
在剖析Oops之前,咱们先来看以下这么一个比如,运用GPIO的中止做掉电检测,参阅《嵌入式Linux开发教程下册》的驱动结构,规划如下程序框图:
这个结构规划之初的抱负流程为:运用发动->程序初始化->运用open设备->等候中止工作,但实践项目开发时,往往产生许许多多不行猜测的工作。如小王正在调Qt运用,发现老王的进程老在打印,那就不让老王的进程开机自发动,调了两三天后,不守时地提示个Oops提示,小王依照“曾经代码不呈现,新加的呈现,那么原因肯定在新代码内”的惯性思想,认为是新加的Qt导致的,然后小王就不断测验,不断查找bug中…….这样就过去了十年。
但原因其实是小王没有open设备,即驱动层没有初始化守时器行列,那么中止处理函数中50ms触发的行列就为一个空值,空指针时Linux内核当然“哎呦”一下提示你了,而不守时地提示其实便是因为电源不守时地松动,gpio检测到掉电了所以触发了中止。
实践上,这样的事例非常常见,原本想A->B->C,实践运用是A->D->C,又或许驱动中有某个变量忘掉初始化等等,这时剖析Oops就能够非常快速地解决问题。那接下来咱们就用Linux中规范驱动去触发一个Oops,对的你没看错,Linux内核规范源码也存在这样的反常,并且咱们也能够去修正这样的问题。
运用我司的EasyARM-iMX283开发板,内核源码为光盘内的Linux-2.6.35.3.tar.bz2,编译办法请参阅光盘材料,咱们需要把lcd的背光驱动修改为ko形式。
烧录完新内核,加载新编译出来的drivers/video/backlight/mxs_bl.ko文件就会提示以下Oops信息:
乍看之下,这段信息跟乱码差不多,但只需你一层层地剖析,你就会发现,这些信息现已告知了咱们过错的原因。接下来就开端咱们的Oops剖析之旅。
1、首要过错信息
用于提示过错的类型,这儿表明运用空指针。
2、操作进口
用于提示过错的操作,这儿表明加载mxs_bl模块时犯错,对应于加载操作insmod mxs_bl.ko。
3、PC指针
用于提示犯错时的PC指针方位,PC指针即当时程序运转点的地址,这儿提示表明过错函数为regulator_set_current_limit,偏移地址为0xc。
4、LR指针
用于提示犯错时的LR指针方位,LR指针即调用子函数的上一个函数名以及进口偏移量,这儿表明上一个函数为set_bl_intensity,偏移地址为0xd8。即set_bl_intensity调用regulator_set_current_limit时犯错。
5、寄存器值
用于记载犯错时各个寄存器的值,关于汇编比较了解的同志们能够研究一下这段信息。
6、犯错进程信息
用于提示犯错的进程id号与进程称号。犯错进程为insmod, PID号2261,关于多任务体系中,或许存在多个PID调用同一个接口的状况。
7、犯错时的仓库信息
用于提示犯错时仓库内保存的寄存器信息,当程序因为中止产生或子程序调用时,会履行压栈操作,行将运转环境保存到仓库内,确保退出中止或跳出子程序后,运转环境不产生改动。
而此处的仓库信息即记载了程序运转时的环境信息。从中咱们能够找到许多LR地址,然后剖分出函数调用联系,与下一段的信息有相似效果。
8、函数履行的回溯联系