众所周知,要想使用gdb调试,那么在编译的时候一定要加上-g选项。因为编译器默认是不加-g选项的。
因此在编译模块的时候,我们需要在Makefile里面添加如下信息:
EXTRA_CFLAGS +=-g
在添加了上面的信息后,我们编译出来的.ko文件,就可以使用gdb来调试了。
我的oops信息如下:
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = 80004000
[00000000] *pgd=00000000
Internal error: Oops: 17 [#1] PREEMPT SMP ARM
Modules linked in: imx_eim(O)
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.9.88 #67
Hardware name: Freescale i.MX7 Dual (Device Tree)
task: 80f06340 task.stack: 80f00000
PC is at tasklet_eim_rev_handle+0x6c/0x170 [imx_eim]
LR is at tasklet_eim_rev_handle+0x158/0x170 [imx_eim]
pc : [<7f000074>] lr : [<7f000160>] psr: 200e0113 //根据pc的值以及System.map可以知道问题在模块里面
sp : 80f01e30 ip : 80fd38e8 fp : 00000101
r10: 40000006 r9 : 80f02080 r8 : 80e77300
r7 : 80f91400 r6 : 00000000 r5 : 7f000e30 r4 : 7f000e00
r3 : 00000002 r2 : 00000000 r1 : 00000102 r0 : 00000000
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c53c7d Table: a86d406a DAC: 00000051
Process swapper/0 (pid: 0, stack limit = 0x80f00210)
Stack: (0x80f01e30 to 0x80f02000)
然后使用通过gdb调试ko文件:
gdb imx_eim.ko
进入gdb后,输入:
l *(tasklet_eim_rev_handle+0x6c)
gdb 就会提示你哪里出问题了,我的提示信息如下:
Reading symbols from imx_eim.ko...done.
(gdb) l *(tasklet_eim_rev_handle+0x6c)
0x74 is in tasklet_eim_rev_handle (./include/linux/dmaengine.h:807).
802 };
803
804 static inline int dmaengine_slave_config(struct dma_chan *chan,
805 struct dma_slave_config *config)
806 {
807 if (chan->device->device_config)
808 return chan->device->device_config(chan, config);
809
810 return -ENOSYS;
811 }
(gdb)
然后我根据gdb的提示,就找到我的问题出在哪里了。
注:如果你没有在Makefile里面添加EXTRA_CFLAGS +=-g信息,那么gdb调试的时候,gdb会提示你如下信息:
Reading symbols from imx_eim.ko...(no debugging symbols found)...done.
(gdb) l *(tasklet_eim_rev_handle+0x6c)
没有符号表被读取。请使用 "file" 命令。
(gdb) q
附录一下我的Makefile,留给自己以后备查:
ARCH=arm
CROSS_COMPILE=arm-poky-linux-gnueabi-
obj-m += imx_eim.o
KDIR := /home/kernel #如果是用于arm平台,则内核路径为arm内核的路径
EXTRA_CFLAGS +=-g
PWD = $(shell pwd)
all:
make ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- -C $(KDIR) M=$(PWD) modules
cp *.ko /nfs
clean:
rm -rf *.o
rm *.ko *.order *.mod.c *.symvers