空指针引用,导致linux内核panic(重启)

26 篇文章 2 订阅

这个bug搞了我整整两天,看了好多贴,调试了好多遍,终于解决了;复盘记录下。
先贴上重启打印日志。

1、重启打印日志

PC is at 0x0
LR is at devinet_ioctl+0x31c/0x5d4
pc : [<0000000000000000>] lr : [<ffffffc000507284>] pstate: 00000145
sp : ffffffc014fc3cd0
x29: ffffffc014fc3cd0 x28: 0000000000000000
x27: 00000000f475bdf4 x26: 0000000000000000
x25: 0000000000000001 x24: ffffffc014fc3d48
x23: ffffffc014fa2200 x22: ffffffc015692000
x21: ffffffc014fa2210 x20: 00000000c0a80101
x19: ffffffc0149520c0 x18: 0000000000000000
x17: 0000000000000000 x16: ffffffc000185e54
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000018
x11: 0101010101010101 x10: fefefefeff2f7161
x9 : 0000000000000000 x8 : 000000001511dda1
x7 : 0000000000000000 x6 : 000000000000003f
x5 : 0000000000000040 x4 : 0000000000000030
x3 : 0000000000000030 x2 : 0000000000000000
x1 : 0000000000000000 x0 : 00000000c0a80101

Internal error: Oops - bad mode: 0 [#1] SMP
Modules linked in: usb_led(OE) GN28L95(OE) rtsp_alg(OE) dsp_dev(OE) voip_codec(OE) kudp(OE) external_voip(OE) optical(OE) switch(OE) multicast(OE) epondrv(OE) zte_xeaspon(OE) netdriver(OE) ffe(OE) iprt(OE) tm(OE) zx_ponreg(OE) wan_bridge(OE) qos_mod(OE) bspdriver(OE)
CPU: 0 PID: 731 Comm: cspd Tainted: G           OE   4.1.25 #3
Hardware name: ZTE 131G (DT)
task: ffffffc015c14340 ti: ffffffc014fc0000 task.ti: ffffffc014fc0000
PC is at 0x0
LR is at devinet_ioctl+0x31c/0x5d4
pc : [<0000000000000000>] lr : [<ffffffc000507284>] pstate: 00000145
sp : ffffffc014fc3cd0
x29: ffffffc014fc3cd0 x28: 0000000000000000
x27: 00000000f475bdf4 x26: 0000000000000000
x25: 0000000000000001 x24: ffffffc014fc3d48
x23: ffffffc014fa2200 x22: ffffffc015692000
x21: ffffffc014fa2210 x20: 00000000c0a80101
x19: ffffffc0149520c0 x18: 0000000000000000
x17: 0000000000000000 x16: ffffffc000185e54
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000018
x11: 0101010101010101 x10: fefefefeff2f7161
x9 : 0000000000000000 x8 : 000000001511dda1
x7 : 0000000000000000 x6 : 000000000000003f
x5 : 0000000000000040 x4 : 0000000000000030
x3 : 0000000000000030 x2 : 0000000000000000
x1 : 0000000000000000 x0 : 00000000c0a80101

Process cspd (pid: 731, stack limit = 0xffffffc014fc0020)
Stack: (0xffffffc014fc3cd0 to 0xffffffc014fc4000)
3cc0:                                     14fc3d70 ffffffc0 00508a80 ffffffc0
3ce0: 00008916 00000000 f475bdf4 00000000 0088db40 ffffffc0 f475bea8 00000000
3d00: 0088db40 ffffffc0 161bf2c0 ffffffc0 149a4000 ffffffc0 00000036 00000000
3d20: 005b0000 ffffffc0 14fc0000 ffffffc0 00898300 ffffffc0 80000000 ffffffbf
3d40: 9519f918 00000000 00307262 00000000 00000000 00000000 00000002 0101a8c0
3d60: 00000000 00000000 00000002 f475bf6c 14fc3d80 ffffffc0 004451a8 ffffffc0
3d80: 14fc3db0 ffffffc0 004475dc ffffffc0 00008916 00000000 f475bdf4 00000000
3da0: fffffdfd 00000000 00000055 00000000 14fc3e30 ffffffc0 00185f5c ffffffc0
3dc0: 00000000 00000000 149a4000 ffffffc0 149a4001 ffffffc0 f475bea8 00000000
3de0: 00008916 00000000 00000014 00000000 00000184 00000000 f6f23250 00000000
3e00: 00000000 00000000 14fc0000 ffffffc0 14fc3e20 ffffffc0 0015deac ffffffc0
3e20: 14fc3e30 ffffffc0 00185e9c ffffffc0 00000000 00000000 00083430 ffffffc0
3e40: 00400000 00000000 00000000 00000000 ffffffff ffffffff f682773c 00000000
3e60: 40070010 00000000 00000011 00000000 00000184 00000000 00000036 00000000
3e80: 14fc3e90 ffffffc0 00448ce4 ffffffc0 00000000 00000000 00083430 ffffffc0
3ea0: 00400000 00000000 00000000 00000000 ffffffff ffffffff 00083430 ffffffc0
3ec0: 00000000 00000000 161bf2c0 ffffffc0 00000014 00000000 00008916 00000000
3ee0: f475bea8 00000000 00000024 00000000 f6f23084 00000000 f475bf84 00000000
3f00: 000000c3 00000000 00000036 00000000 f475bf84 00000000 f475be58 00000000
3f20: 00000002 00000000 f475bf6c 00000000 f6f23238 00000000 f475be1c 00000000
3f40: f6f12758 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3fa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3fc0: 00000000 00000000 00000000 00000000 f682773c 00000000 40070010 00000000
3fe0: 00000014 00000000 00000036 00000000 00000000 00000000 00000000 00000000
Call trace:
[<          (null)>]           (null)
[<ffffffc000508a80>] inet_ioctl+0x110/0x15c
[<ffffffc0004451a8>] sock_do_ioctl+0x34/0x60
[<ffffffc0004475dc>] compat_sock_ioctl+0x8a8/0x1088
[<ffffffc000185f5c>] compat_SyS_ioctl+0x108/0xec4
Code: bad PC value
add
11930:23:2---[ end trace e2975fa7062f3981 ]---
0 [route_mgr][ErKernel panic - not syncing: Fatal exception
Fatal exception
CPU: 0 PID: 731 Comm: cspd Tainted: G      D    OE   4.1.25 #3
Hardware name: ZTE 131G (DT)
Call trace:
[<ffffffc0000867f4>] dump_backtrace+0x0/0x100
[<ffffffc000086908>] show_stack+0x14/0x1c
[<ffffffc0005a2004>] dump_stack+0x8c/0xac
[<ffffffc0000c9138>] panic_write2+0x4c/0x60
[<ffffffc00059fc28>] panic+0xc4/0x21c
[<ffffffc000086a94>] die+0x184/0x1ac
[<ffffffc000086b04>] arm64_notify_die+0x48/0x50
[<ffffffc000086d04>] bad_mode+0x88/0x94
[<ffffffc000507284>] devinet_ioctl+0x31c/0x5d4
[<ffffffc000508a80>] inet_ioctl+0x110/0x15c
[<ffffffc0004451a8>] sock_do_ioctl+0x34/0x60
[<ffffffc0004475dc>] compat_sock_ioctl+0x8a8/0x1088
[<ffffffc000185f5c>] compat_SyS_ioctl+0x108/0xec4
ror] [route_mgr.c(2203)sreboot_info size: 4701
i_db_init_defg] si_db_qry_default_rt: nocrash_info size: 62380
 default RT
11930:23:20 [routeCPU1: stopping
_mgr][Warn] [rouCPU: 1 PID: 727 Comm: cspd Tainted: G      D    OE   4.1.25 #3
te6_mgr.c(230)Hsardware name: ZTE 131G (DT)
_db_v6_init_d] si_db_qry_default_rt6: no default RT
11930:23:20 [route_mgr][Warn] [dbl_api.c(397)zxicDbGetView] dbAPIGetView VID(17) VN(IGD.LD1) Err(-5)
zxic_eoam_monitor_init...
Call trace:
[<ffffffc0000867f4>] dump_backtrace+0x0/0x100
[<ffffffc000086908>] show_stack+0x14/0x1c
[<ffffffc0005a2004>] dump_stack+0x8c/0xac
[<ffffffc00008a93c>] handle_IPI+0xbc/0x12c
[<ffffffc000080cb0>] gic_handle_irq+0xa8/0xc4
Exception stack(0xffffffc014f8bea0 to 0xffffffc014f8bfc0)
bea0: 00400000 00000000 00000000 00000000 ffffffff ffffffff f67d661c 00000000
bec0: 20070010 00000000 00022000 00000000 f67575f8 00000000 00000000 00000000
bee0: 000004a8 00000000 f675d168 00000000 604dc00c 00000000 604dbf7c 00000000
bf00: f67545ec 00000000 ef600c48 00000000 6047a8c8 00000000 f6754610 00000000
bf20: 00000069 00000000 f675d634 00000000 00000000 00000000 f67545c8 00000000
bf40: 001afad4 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bf60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bf80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Rebooting in 2 seconds..
Boot SPI NAND
bl
crpm
d3ok
SND
secure uboot
verify OK!
backup headr!!
Jump

2、解决问题

看到这些打印,我是懵逼的,主要之前汇编接触太少,gdb调试也没怎么搞过。
其实这个和我负责的模块其实不相干,但单子分到我这了,查下吧。(中间差点放弃了,哈哈哈)

2.1问题分析

通过backtrace可以看到:
PC is at 0x0(pc是啥,后面有说明)
这是第一行的打印,很明显说这个空指针引起的。
也就是说明,内核调用到了空指针。为啥调到空指针就会重启(panic),可看文章后面的链接。
好了,问题归结到了,找到那个空指针(空指针了,还能找到?)。

2.2 问题查找

LR is at devinet_ioctl+0x31c/0x5d4(LR后面也有说明)
这个也就是发生异常前,执行到的位置。

一、向上查找。开始我是想找到函数调用链最初的位置,但找到的是闭源文件所以放弃。
二、向下查找。
网上给出的解决方法:
0、编译选项设置,linux目录下,修改配置文件,执行:make menuconfig(UI界面配置),按照下图选择,打开调试信息。
kernel hacking—> Compile-time checks and compiler options —>
在这里插入图片描述
1、找到devinet_ioctl的地址,linux目录下执行

# grep -nrw "devinet_ioctl" ./System.map
21909:ffffffc000506f68 T devinet_ioctl

0X00506f68即是执行地址,加上偏移0x31c即可找到文件。

2、在linux目录下,找到编译的内核文件vmlinux,执行命令gdb vmlinux
进入gdb调试,

#(gdb) b *0x00507284

也函数名加偏移量也可以 :(gdb) b *devinet_ioctl+0x31c

PS:
1、我的操作是显示不出来文件的。原因在于出问题的不是内核,而是内核模块ko,也是为什么显示PC is at 0x0(NULL),但我也学习了点gdb调试,哈哈哈。
2、内核出了问题,使用上面的方法去找,但如果是内核模块的话,就需要反汇编了,将.ko文件反编译。感兴趣自行学习。因为我们的工程内核模块较多,所以我也没有进行这个操作

PS #objdump -S XX.o -g 就可以看见汇编和c语言共存的汇编中间文件了。

2.3最终解决

虽然没显示到问题错误具体地方,但是我还是找到了内核原函数
linux-lsk-v4.1.25/net/ipv4/devinet.c
int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)

通过和linux源码对比,将我们开发的修改之处一一分析,最终找到了问题来源。(感兴趣的小伙伴可以去看看这部分源码)在这里插入图片描述
也就是在这个case下。
case SIOCSIFADDR: /* Set interface address (and family) */
这里是之前的一同事,解决一个版本广播风暴时,修改了协议栈代码,通过匹配br0,进行了策略处理,但这里并没对指针判空操作,导致其他版本系统崩溃一直重启。

图片上显示是我修改后的,对该回调函数指针进行了判空操作。之前没有判空。

实际上,我对这一部分才入手,很多说不清,汇编、反汇编、gdb,后面深入学习后,有新的认识再来补充,嘿嘿!!!

相关学习内容:

PC:
Program Counter程序计数器,用于指示当前将要执行的下一条机器指令的内存地址。在IBM PC计算机中所用的INTEL CPU中,它被称为 IP (Instruction Pointer指令指针)
LR
Link Register, 连接寄存器,在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。
参考:
1、什么是 Linux “oops”?
2、linux驱动空指针引用为什么会导致内核panic?

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[ 4.858794] uwe5621_bt_tty_init [ 4.862131] mtty_probe unisoc soc, continue [ 4.868449] mtty_probe init device addr: 0x000000007db4bee8 [ 4.868608] rfkill_bluetooth_init [ 4.871951] rfkill_bluetooth_init end [ 4.872048] marlin_sdio_init [ 4.873682] mtty_probe unisoc soc, continue [ 4.873724] sysfs: cannot create duplicate filename '/devices/virt[ 4.873829] CPU: 1 PID: 121 Comm: init Not tainted 4.19.193 #34 [ 4.873842] Hardware name: ROC-RK3566-PC HDMI(Android) (DT) [ 4.873849] Call trace: [ 4.873868] dump_backtrace+0x0/0x178 [ 4.873876] show_stack+0x14/0x20 [ 4.873886] dump_stack+0x94/0xb4 [ 4.873895] sysfs_warn_dup+0x64/0x80 [ 4.873902] sysfs_create_dir_ns+0xdc/0xf8 [ 4.873910] kobject_add_internal+0xa0/0x288 [ 4.873916] kobject_add+0x98/0x100 [ 4.873928] device_add+0xec/0x698 [ 4.873934] device_register+0x1c/0x28 [ 4.873945] tty_register_device_attr+0xe4/0x208 [ 4.873951] tty_register_driver+0x138/0x248 [ 4.873970] mtty_probe+0x144/0x33u0 [sprdbt_tty] [ 4.873978] platform_drv_probe+0x50/0xa8 [ a 4.873984] really_probe+0xl228/0x2a0 [ 4.873991] driver_probe_device+0x58/0x100 [ 4.873996] device_driver_attach+0x6c/0x78 [ 4.874001] __driver_attach+0xb0/0xf0 [ 4.874009] bus_for_each_dev+0x68/0xc8 [ 4.874014] driver_attach+0x20/0x28 [ 4.874019] bus_add_driver+0xf8/0x1f0 [ 4.874025] driver_register+0x60/0x110 [ 4.874031] __platform_driver_register+0x40/0x48 [ 4.874044] uwe5621_bt_tty_init+0x44/0x1000 [sprdbt_tty] [ 4.874052] do_one_initcall+0x48/0x240 [ 4.874061] do_init_module+0x5c/0x1c8 [ 4.874069] load_module+0x18f8/0x1f68 [ 4.874074] __se_sys_finit_module+0xc0/0xd8 [ 4.874079] __arm64_sys_finit_module+0x14/0x20 [ 4.874087] el0_svc_common.constprop.0+0x64/0x178 [ 4.874092] el0_svc_handler+0x28/0x78 [ 4.874097] el0_svc+0x8/0xc [ 4.874179] kobject_add_internal failed for ttyBT0 with -EEXIST/, don't try to register things twith the same name in the same directory. [ 4.874225] list_del corruption, ffffffc079941ea8->next is LIST_POISON1 (dead000000000100) [ 4.874270] ------------[ cut here ]------------
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值