在修改驱动或应用时经常会遇到关于指针的报错,如野指针、空指针或访问已被释放的指针。 这种报错通常只提供一个虚拟地址,且经常会导致内核崩溃,定位问题比较困难。
在排查这种报错可以利用交叉编译链的adb工具和内核自带的vmlinux工具
操作步骤如下
1、收集调试信息中的报错 例如:
[
152.040585] Unable to
handle kernel NULL pointer dereference at virtual address 00000130
[
152.049422] pgd = e2760000
[
152.052602] [00000130] *pgd=62790831, *pte=00000000, *ppte=00000000
[
152.059460] Internal error: Oops: 17 [#1] PREEMPT SMP ARM
[
152.062585] Modules linked in: mali(O) gt9xxnew_ts
[
152.062585] CPU: 0 PID: 1275 Comm: init Tainted: G W
O 3.10.65 #108
[
152.062585] task: e252ed80 ti: e2e1e000 task.ti: e2e1e000
[
152.062585] PC is
at pinctrl_dt_to_map+0x20/0x26c
[
152.062585] LR is
at pinctrl_get+0x130/0x3d8
[
152.062585] pc : [<c028ae74>]
lr : [<c0288030>] psr:
a00a0013 2、调用adb工具进入调试模式 forlinx@ubuntu:~/a40i/lichee/linux-3.10$ ../out/sun8iw11p1/linux/common/buildroot/host/opt/ext-toolchain/bin/arm-linux-gnueabihf-gdb vmlinux 3、根据调试信息,定位问题点 forlinx@ubuntu:~/a40i/lichee/linux-3.10$ ../out/sun8iw11p1/linux/common/buildroot/host/opt/ext-toolchain/bin/arm-linux-gnueabihf-gdb vmlinux GNU gdb (Linaro_GDB-2016.05) 7.11.1.20160702-git Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: 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 "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from vmlinux...done. (gdb) (gdb) (gdb) l *(pinctrl_dt_to_map+0x20) 0xc028ae74 is in pinctrl_dt_to_map (drivers/pinctrl/devicetree.c:177). 172 return dt_remember_or_free_map(p, statename, NULL, map, 1); 173 } 174 175 int pinctrl_dt_to_map(struct pinctrl *p) 176 { 177 struct device_node *np = p->dev->of_node; 178 int state, ret; 179 char *propname; 180 struct property *prop; 181 const char *statename; (gdb) l *(pinctrl_get+0x130/0x3d8) 0xc0287f00 is in pinctrl_get (drivers/pinctrl/core.c:822). 817 /** 818 * pinctrl_get() - retrieves the pinctrl handle for a device 819 * @dev: the device to obtain the handle for 820 */ 821 struct pinctrl *pinctrl_get(struct device *dev) 822 { 823 struct pinctrl *p; 824 825 if (WARN_ON(!dev)) 826 return ERR_PTR(-EINVAL); (gdb)
gdb工具可以定位到具体是哪一个文件里的哪一行造成的报错。根据提示自行修改即可。
|