使用GDB调试Linux内核空指针问题

您所在的位置:网站首页 gdb调试linux内核 使用GDB调试Linux内核空指针问题

使用GDB调试Linux内核空指针问题

2023-10-09 23:54| 来源: 网络整理| 查看: 265

1.概述

在Linux内核开发中,我们会经常遇到访问空指针导致内核Oops或panic。遇到这种问题,需要先定位出是哪一个函数、哪一个变量导致的异常。通常情况下,Linux内核会打印出异常时的栈、模块、CPU寄存器等信息,但某些情况下,栈被破环,只能输出寄存器信息(U-Boot发生异常时只会输出寄存器信息),那我们只能根据寄存器信息还原出发生异常时的现场。

2,实例

如下图所示,内核明确的出了异常原因-访问空指针,空指针解引用地址为0x00000003(若异常地址不为0,应该是访问了某个结构体中的变量,加上了偏移地址),发生异常的函数为__dwc3_gadget_ep_set_halt,上一个调用函数为dwc3_ep0_stall_and_restart。

Oops

pc寄存器保存了CPU执行的指令地址(0xffffff8008734ae4),可以根据该地址得到异常发生时调用的函数和访问的变量,lr保存了上一个调用函数的地址(0xffffff80087369e4)。下面使用gdb,还原发生异常时的现场。

首先启动aarch64-linux-gnu-gdb,使用file命令读取vmlinux镜像,获取Linux内核的所有符号。

gdb_file

使用list命令获取指令地址附件的符号。 如下图所示,0xffffff8008734ae4地址在__dwc3_gadget_ep_set_halt函数中,内部调用了usb_endpoint_xfer_isoc内联函数,异常就发生在该内联函数中。

list

__dwc3_gadget_ep_set_halt函数部分代码如下,三个参数分别使用x0、x1、x2寄存器传递,内部调用了usb_endpoint_xfer_isoc内联函数。

[drivers/usb/dwc3/gadget.c] int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) { struct dwc3_gadget_ep_cmd_params params; struct dwc3 *dwc = dep->dwc; int ret; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); return -EINVAL; } memset(¶ms, 0x00, sizeof(params)); ...... return ret; }

如下图所示,lr寄存器保存的地址指向了dwc3_ep0_stall_and_restart函数,该函数内部调用了__dwc3_gadget_ep_set_halt函数。

list_lr

使用x命令获取异常指令附近的汇编代码。可以使用x/20i 0xffffff8008734ae4命令获取异常地址以后的20条汇编指令,也可以使用x/20i __dwc3_gadget_ep_set_halt命令直接获取发生异常的函数的汇编代码。上面已经明确了发生异常的函数,因此这里直接获取该函数的汇编代码,便于分析。 如下图红框3所示,异常地址0xffffff8008734ae4处是一条内存加载指令,将x0寄存器中保存的地址加2得到一个新的地址,再将该地址处的一个字节的数据保存到w0寄存器中。x0寄存器由红框2更新,其保存的数据来自于x19寄存器保存的地址加56。如红框1所示,x19寄存器的值又来自于x0,而x0是函数的第一个参数,即端点数据结构struct dwc3_ep的地址,地址为x19: ffffffc0f0b5c400。红框2和红框3都是对struct dwc3_ep数据结构内部变量的访问,偏移值56和3是内部变量相对于结构体基地址的偏移。

x

上面我们已经明确了发生异常的函数和访问的数据结构,现在我们需要根据偏移值确定访问的具体变量。 使用ptype /o struct dwc3_ep命令获取struct dwc3_ep数据结构各个变量的偏移值.如下图所示,偏移值为56的变量为struct usb_ep结构体中的desc变量,即端点描述符的地址。

ptype_dwc3_ep

使用ptype /o struct usb_endpoint_descriptor命令获取struct usb_endpoint_descriptor数据结构各个变量的偏移值。如下图所示,偏移值为3的变量为bmAttributes,即端点的属性。

ptype_usb_endpoint_desc

从上面的分析中可以看出,红框3中[x0, #3]=0x00000003,x0中保存的地址为NULL,即指针变量desc是一个空指针,空指针解引用时发生了异常,也即在内联函数usb_endpoint_xfer_isoc中访问bmAttributes变量导致了异常。后续我们只需要排查是什么原因导致了指针变量desc变为空指针即可。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3