1.概述

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

2,实例

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

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

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

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

__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(&params, 0x00, sizeof(params));......return ret;
}

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

  1. 使用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是内部变量相对于结构体基地址的偏移。

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

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

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

使用GDB调试Linux内核空指针问题相关推荐

  1. qemu debug linux内核,在QEMU环境中使用GDB调试Linux内核

    简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...

  2. Vmware+gdb调试Linux内核——工欲善其事,必先利其器

    今天我最终忍受不了qemu的低速跟不可理喻的各种bug,開始寻找新的调试内核的方法.然后想到了Vmware,那么成熟的虚拟机怎么可能调试不了内核.于是尝试了一番,发现结果很的棒!所以立刻奋笔疾书.把这 ...

  3. qemu+gdb调试linux内核

    文章目录 编译内核 下载qemu 构建initramfs根文件系统 1.编译Busybox 2.生成initrd 3.测试根文件系统 gdb调试内核 参考文献 编译内核 # make menuconf ...

  4. 利用QEMU+GDB搭建Linux内核调试环境

    前言 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试. 其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qe ...

  5. linux问号符号,调试linux内核时gdb中的问号符号4.10

    我想从linux内核中的函数start_kernel()调试linux内核.调试linux内核时gdb中的问号符号4.10 这基本上就是我已经做了 从kernel.org 下载4.10内核源提取源后: ...

  6. 使用 ftrace 调试 Linux 内核【转】

    转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...

  7. 用 GDB 调试Linux程序及有用技巧

    用 GDB 调试Linux程序及有用技巧(转) armlinux   2008-06-19 10:48   阅读91   评论0 字号: 大大  中中  小小 GNU的调试器称为gdb,该程序是一个交 ...

  8. 使用openocd调试Linux内核,OpenOCD-JTAG调试

    title: OpenOCD-JTAG调试 tags: ARM date: 2018-10-13 23:36:28 Todo [ ] JTAG 调试linux内核 [ ] linux下使用OpenOC ...

  9. 使用openocd调试Linux内核,OpenOCD-JTAG调试(示例代码)

    目录 title: OpenOCD-JTAG调试 tags: ARM date: 2018-10-13 23:36:28 --- Todo [ ] JTAG 调试linux内核 [ ] linux下使 ...

最新文章

  1. 接私活福音,validation组件敏捷开发,效率提升5倍!
  2. leetcode 752. 打开转盘锁 c代码
  3. epoll(eventpoll)是干嘛的?IO多路转接技术(相较select、poll的优点)
  4. bean定义的继承 - Spring Framework reference 2.0.5 参考手册中文版
  5. 大数据时代的数据存储,非关系型数据库MongoDB(一)(转)
  6. Django 【第十九篇】JS实现的ajax、同源策略和前端JSONP解决跨域问题
  7. php取汉字拼音首字母,php获取汉字拼音首字母的函数(真正可以使用的)
  8. 基于jquery的全局ajax函数处理session过期后的ajax操作
  9. (转帖出自ESRI BBS)有关于GIS思想
  10. CruiseControl.NET and MSBuild
  11. win10自带邮件mail登录qq邮箱126邮箱等时提示需注意的解决办法
  12. Ceph 网络模块(1) - 网络模块基本结构
  13. Qt自带示例演示程序
  14. Educoder-练习-Java循环综合练习四之日历打印
  15. 如何把计算机组成原理、操作系统、数据结构和计算机网络融会贯通,相互联系起来?
  16. Java静态类的使用
  17. 四. 常用EMC防护器件选型学习笔记
  18. 计算机组成原理第二章:运算方法和运算器
  19. 电力节能设备远程监控系统解决方案
  20. BMZCTF-Web WriteUp

热门文章

  1. 【Hadoop基础教程】7、Hadoop之一对一关联查询
  2. 扶贫工作-结对帮扶公示牌 自动化填写
  3. LS1046A 启动流程分析
  4. 专转本-计算机二级习题1
  5. 逻辑回归logistic原理(python代码实现)
  6. 【RK3399】[Android 6.0] linux4.4 调试8723BU记录过程
  7. Error occured processing XML 'Cannot find class [springmvc.extention.BeanArgumentResolver]
  8. 安利超实用的游戏技能特效素材!
  9. typeAliasesPackage的作用
  10. camunda如何插入以及获取流程审批