问题背景:
当前项目跑GTS时候, 发现当使用usb2.0线连接PC时候, 运行测试指令后, 一切准备部分和运行测试部分都是ok的;但是使用usb3.0线的连接PC跑的时候, 运行测试指令后,在准备部分程序跑之后,手机会死机进入dump模式.
问题分析:
一开始接手这个问题,根据现象, 首先想到usb2.0, usb3.0的区别. 可能除了从usb头颜色做区分和带宽速度不一样外,暂无其他想法.
第二部, 从解析的dump的kernel log 分析信息, 解析文件如下:
2005.337355: <2> Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
.............................................................................................................................................
2005.337795: <2> pc : config_ep_by_speed_and_alt+0x90/0x308 2005.337813: <2> lr : audio_set_alt+0x30/0x54 2005.337821: <2> sp : ffffffc0148539a0 2005.337829: <2> x29: ffffffc0148539b0 x28: 0000000000000021 2005.337841: <2> x27: 0000000000000001 x26: 0000000000007fff 2005.337853: <2> x25: ffffffe8c6343280 x24: ffffff9a8357cd20 2005.337865: <2> x23: 0000000000000001 x22: ffffffe8c634329c 2005.337876: <2> x21: 0000000000000064 x20: ffffff9a92ad33a8 2005.337888: <2> x19: ffffffe8c76f40b0 x18: ffffffc011afd070 2005.337899: <2> x17: 0000000000000031 x16: ffffffe8c63138b0 2005.337911: <2> x15: 000000000015000f x14: 0000000000000001 2005.337922: <2> x13: 0000000000000005 x12: 0000000000000081 2005.337933: <2> x11: 0000000000000025 x10: 0000000000000000 2005.337944: <2> x9 : 0000000000000001 x8 : ffffffe8c76f40d0 2005.337956: <2> x7 : 0000000000000000 x6 : 000000000000003f 2005.337967: <2> x5 : ffffffc014853940 x4 : 0000000000000000 2005.337978: <2> x3 : 0000000000000000 x2 : ffffff9a96642200 2005.337990: <2> x1 : ffffffe8c76f40b0 x0 : ffffff9a92ad33a8 2005.338003: <2> Call trace: 2005.338016: <2> config_ep_by_speed_and_alt+0x90/0x308 2005.338029: <2> audio_set_alt+0x30/0x54 2005.338040: <2> set_config+0x264/0x478 2005.338050: <2> composite_setup+0x3b0/0x1754 2005.338065: <2> android_setup+0x11c/0x180 2005.338080: <2> dwc3_ep0_set_config+0x484/0x718 2005.338091: <2> dwc3_ep0_inspect_setup+0x234/0x334 2005.338101: <2> dwc3_ep0_interrupt+0xa8/0x3d0 2005.338112: <2> dwc3_process_event_entry+0x144/0x77c 2005.338128: <2> dwc3_process_event_buf+0x6c/0x4e4 2005.338140: <2> dwc3_bh_work+0x74/0x10c 2005.338156: <2> process_one_work+0x2cc/0x558 2005.338169: <2> worker_thread+0x2ac/0x508 2005.338182: <2> kthread+0x16c/0x17c 2005.338197: <2> ret_from_fork+0x10/0x18 2005.338215: <2> Code: 14000003 91008028 52800029 f940010a (f9400148) 2005.338228: <2> ---[ end trace 7483112925a6045f ]--- 2005.338240: <2> Kernel panic - not syncing: Fatal exception in interrupt
所以提取信息如下:
1. 这个是空指针导致的内核崩溃问题: NULL pointer dereference at virtual address
2. 等待返回函数是audio_set_alt, 运行函数是config_ep_by_speed_and_alt, 具体行号需要解析.
3. 整体场景函数调用栈是:
2005.338003: <2> Call trace:
2005.338016: <2> config_ep_by_speed_and_alt+0x90/0x308
2005.338029: <2> audio_set_alt+0x30/0x54
2005.338040: <2> set_config+0x264/0x478
2005.338050: <2> composite_setup+0x3b0/0x1754
2005.338065: <2> android_setup+0x11c/0x180
问题dump :
因为不熟悉符号表代码行号解析,只能在函数添加多处打印,发现问题在
function: config_ep_by_speed_and_alt
在for_each_desc(speed_desc, d_spd, USB_DT_INTERFACE) 处发生异常.
其中有可能是NULL 有且只有speed_desc. 然后再往上看代码,发现speed_desc 赋值是
由判断usb_gadget的speed 来决定是被fs_descriptors, hs_descriptors, ss_descriptors, ssp_descriptors的其中一个来赋值的. 上述这些都是usb usb_descriptor_header的多个变量. 分别对应着usb1.0, usb2.0,usb3.0.
查看这些变量的实现函数usb_assign_descriptors, 和项目全局对于这个函数发现, 其他类对于这个audio bind 时候大都会调用usb_assign_descriptors来实现usb_descriptor_header.
但是在f_audio_source.c 看, 关于audio 类关于usb bind函数(audio_bind) 看, 只是实现了fs 和hs 部分,对于ss , sp 并没有实现. 也就是关于audio 这两类usb_descriptor_header都是NULL状态.
然后回到调用栈, 会发现相关设置函数走的就是audio相关的, 所以在config_ep_by_speed_and_alt函数中, 参数struct usb_function *f 是相关audio的, 并且f->ss_descriptors是一个空值,又是一个指针,所以后续使用就出现一个空指针情况.
解决方案:
跟测试确认GTS 测试本身是没有要求一定使用usb2.0 的线还是usb3.0的线进行测试的,所以本身测试结果是不相管这个配置区别的.所以, 也就是降原来代码基础上加上判空处理,当为空时走2,0部分逻辑.