访问空指针出panic

发布时间 2023-09-25 11:13:22作者: 枝桠

panic信息:

<4>[1670581299] 15:Failed on write i2cdev=23(I2CDEV_RFSW0)
<4>[1670581299] 15:tx retry failed
<4>[1670581299] 15:Failed on write i2cdev=23(I2CDEV_RFSW0)
<1>[1670595592] 4:CPU 4 Unable to handle kernel paging request at virtual address 00000040, epc == c00f341c, ra == c00f341c
<4>[1670595592] 4:Oops[#1]:
<4>[1670595592] 4:Cpu 4
<4>[1670595592] 4:$ 0   : 00000000 1000dc00 00000000 00000001
<4>[1670595592] 4:$ 4   : c697f590 1000dc01 8cbfbd74 c6980000
<4>[1670595592] 4:$ 8   : 1000dc01 00000001 00000fff 2002044b
<4>[1670595592] 4:$12   : 00000008 00010000 00000000 01000201
<4>[1670595592] 4:$16   : c00f0000 8cbfbd74 00000000 863769f8
<4>[1670595592] 4:$20   : 00000095 c0100000 c6990000 0089e86c
<4>[1670595592] 4:$24   : 00000008 2baf6e1c                  
<4>[1670595592] 4:$28   : 8cbfa000 8cbfbd18 5c9ef038 c00f341c
<4>[1670595592] 4:Hi    : 00594b2d
<4>[1670595592] 4:Lo    : 502d5d2c
<4>[1670595592] 4:epc   : c00f341c casa_knet_tx_buffer+0x80/0x4d4 [linux_casa_knet]
<4>[1670595592] 4:    Tainted: P         
<4>[1670595592] 4:ra    : c00f341c casa_knet_tx_buffer+0x80/0x4d4 [linux_casa_knet]
<4>[1670595592] 4:Status: 1000dc03    KERNEL EXL IE 
<4>[1670595592] 4:Cause : 1080000c
<4>[1670595592] 4:BadVA : 00000040
<4>[1670595592] 4:PrId  : 000c4003 (XLS616 Rev B1)
<4>[1670595592] 4:Modules linked in: linux_kbp_driver(P) kmod_util(P) kcasalog(P) linux_casa_knet(P) linux_bcm_knet(P) linux_uk_proxy(P) linux_user_bde(P) linux_kernel_bde(P) zbbusctr spi_sc18is602 i2c_xlr
<4>[1670595592] 4:Process ddm_cm_remote_q (pid: 2482, threadinfo=8cbfa000, task=8c9d6058, tls=5c9f7700)
<4>[1670595592] 4:Stack : c00f22cc 1000dc01 8621608c 00789f50 00000000 8cbfbd74 00000000 8cbfbd74
<4>[1670595592] 4:        8cbfbe20 83464c34 c00f2a84 00000006 0000008d c00f3a18 836c0f84 86313df8
<4>[1670595592] 4:        c697f594 8d1ca404 00000018 83698e58 8cbfbae4 1d3879bc 863769f8 00000000
<4>[1670595592] 4:        00000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[1670595592] 4:        00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[1670595592] 4:        ...
<4>[1670595592] 4:Call Trace:
<4>[1670595592] 4:[<c00f341c>] casa_knet_tx_buffer+0x80/0x4d4 [linux_casa_knet]
<4>[1670595592] 4:[<c00f3a18>] casa_knet_tx_api_tx+0x1a8/0x340 [linux_casa_knet]
<4>[1670595592] 4:[<c00f1294>] casa_knet_ioctl+0xa4/0xe8 [linux_casa_knet]
<4>[1670595592] 4:[<834d5044>] vfs_ioctl+0x3c/0xf8
<4>[1670595592] 4:[<834d5414>] do_vfs_ioctl+0x314/0x44c
<4>[1670595592] 4:[<834d55a4>] sys_ioctl+0x58/0xc0
<4>[1670595592] 4:[<83402f54>] stack_done+0x20/0x3c
<4>[1670595592] 4:
<4>[1670595592] 4:
<4>[1670595592] 4:Code: 244225e8  0040f809  00000000 <ac520040> ac40003c  ac400000  ac53000c  ac540010  00408021 

我们看Call Trace的最顶层

<4>[1670595592] 4:[<c00f341c>] casa_knet_tx_buffer+0x80/0x4d4 [linux_casa_knet]

0xc00f341c是进程空间里的地址,casa_knet_tx_buffer是此调用函数,这个0x80很重要,是出问题时在函数casa_knet_tx_buffer()中的偏移位置
所以,找到这个位置就ok了

首先查看出问题的时间和linux_casa_knet的改动时间,期间没有别的提交,所以,用现在此时的代码就行

1、用nm命令查看函数casa_knet_tx_buffer()在ko里的位置:

zyc@fish zyc_88x $ mips64-unknown-linux-gnu-nm sdk/build/linux-smm_xls/smm_xls/linux-casa-knet.ko | grep casa_knet_tx_buffer
0000a61c T casa_knet_tx_buffer

注意:要使用适用于目标平台的交叉编译工具链里的nm

2、加上偏移位置
0x0000a61c + 0x80 = 0xa69c

3、addr2line确定位置:

zyc@fish zyc_88x $ /opt/rmi/1.6/mipscross/nptl/bin/mips64-unknown-linux-gnu-addr2line -e sdk/build/linux-smm_xls/smm_xls/linux-casa-knet.ko 0xA69C
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:897



或者,用objdump出来看看也行

zyc@fish zyc_88x $ /opt/rmi/1.6/mipscross/nptl/bin/mips64-unknown-linux-gnu-objdump -dlS sdk/build/linux-smm_xls/smm_xls/linux-casa-knet.ko > dump.log
    // Get a struct for multiport
    mports = ktx_mport_alloc();
    a68c:       3c020000        lui     v0,0x0
    a690:       24420000        addiu   v0,v0,0
    a694:       0040f809        jalr    v0
    a698:       00000000        nop
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:914

    // clear out next pointer
    mports->next = NULL;

    // save context
    mports->context = context;
    a69c:       ac520040        sw      s2,64(v0)  # ---- addr:0xa69c
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:897
        return -1;
    }

    // Get a struct for multiport
    mports = ktx_mport_alloc();
    mports->retry=0;
    a6a0:       ac40003c        sw      zero,60(v0)
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:911
        casa_knet_swm_packet_io_free_buffer(buffer);
        return -1;
    }

    // clear out next pointer
    mports->next = NULL;
    a6a4:       ac400000        sw      zero,0(v0)
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:918
    // save context
    mports->context = context;

    // initialize parameter struct to call bcm knet
    tdata = &mports->tx_data;
    tdata->buffer = (uint8_t *)buffer;
    a6a8:       ac53000c        sw      s3,12(v0)
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:931
        memset(&buffer[length], 0x00, 64 - length);
        length = 64;
    }
#endif

    tdata->length = length;
    a6ac:       ac540010        sw      s4,16(v0)
/vob/zyc_88x/sdk/systems/linux/kernel/modules/casa-knet/casa-knet-tx.c:896
        casa_knet_swm_packet_io_free_buffer(buffer);
        return -1;
    }


源码:

    // Get a struct for multiport
    mports = ktx_mport_alloc();
    mports->retry=0;    // 这里
    //  NULL check
    if (NULL == mports)
    {
        // in case tracing
        DEBUG_FLAP_DROP_TX(buffer, DEBUG_FLAP_DROP_NO_TX_RES);

        CASA_KNET_PRINTK_NON_DEBUG("%s Out of multiport transmit structures, dropping packet\n", __FUNCTION__);
        casa_knet_swm_packet_io_free_buffer(buffer);
        return -1;
    }