上一篇我们大概聊了如何写一个简单的字符设备驱动,我们不是神,写代码肯定会出现问题,我们需要在编写代码的过程中不断调试。在普通的c应用程序中,我们经常使用printf来输出信息,或者使用gdb来调试程序,那么驱动程序如何调试呢?我们知道在调试程序时经常遇到的问题就是野指针或者数组越界带来的问题,在应用程序中运行这种程序就会报segmentationfault的错误,而由于驱动程序的特殊性,出现此类情况后往往会直接造成系统宕机,并会抛出oops信息。那么我们如何来分析oops信息呢,甚至根据oops信息来定位具体的出错的代码行呢?下面就根据一个简单的实例来说明如何调试驱动程序。 如何根据oops定位代码行我们借用linux设备驱动第二篇:构造和运行模块里面的helloworld程序来演示出错的情况,含有错误代码的helloworld如下: #includelinux/init.h#includelinux/module.hMODULE_LICENSE(DualBSD/GPL);staticinthello_init(void){char*p=NULL;memcpy(p,test,4);printk(KERN_ALERTHello,world\n);return0;}staticvoidhello_exit(void){printk(KERN_ALERTGoodbye,cruelworld\n);}module_init(hello_init);module_exit(hello_exit); Makefile文件如下: ifneq($(KERNELRELEASE),)obj-m:=helloworld.oelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildPWD:=$(shellpwd)default:$(MAKE)-C$(KERNELDIR)M=$(PWD)modulesendifclean:rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versionsmodules.orderModule.symvers 很明显,以上代码的第8行是一个空指针错误。insmod后会出现下面的oops信息: [.]BUG:unabletohandlekernelNULLpointerdereferenceat(null)[.]IP:[ffffffffcd]hello_init+0xd/0x30[helloworld][.]PGD0[.]Oops:[#1]SMP[.]Moduleslinkedin:helloworld(OE+)vmw_vsock_vmci_transportvsockcoretempcrct10dif_pclmulcrc32_pclmulghash_clmulni_intelaesni_intelvmw_balloonsnd_ensaes_x86_64lrwsnd_ac97_codecgfmulglue_helperablk_helpercryptdac97_busgameportsnd_pcmserio_rawsnd_seq_midisnd_seq_midi_eventsnd_rawmidisnd_seqsnd_seq_devicesnd_timervmwgfxbtusbttmsnddrm_kms_helperdrmsoundcoreshpchpvmw_vmcii2c_piix4rf北京那家医院治疗白癜风比较好白癜风如何确诊治疗好
|