温暖的电波  

背景

内核发生了非法地址访问产生了panic;根据panic信息拿到了发生panic的异常指令发生的虚拟地址;根据异常指令地址和内核镜像vmlinux可以找到对应的内核代码位置(可以精确到某个文件的某一行),然后就开始反汇编,对寄存器,查看是访问哪个变量出了问题。

在这个过程中经常要去计算一个结构体中某个成员的偏移,而有些成员又是一个结构体,又或者结构体中有些成员会根据内核配置的差异而导致其size不同,这个时候就需要去确认发生了panic的内核运行过程中这个结构体中的成员的偏移究竟是多少。在没有生成kdump的情况下(例如,一些嵌入式单板资源有限),如何确认呢?

 

解决方法

使用gdb+vmlinux可以确认。

示例1:查看随配置不同而size不同的类型运行时的实际size

通过p sizeof(type)命令即可实现该目标:

  • 第一步:gdb加载vmlinux
gdb vmlinux

 

  • 第二步:
(gdb) p sizeof(spinlock_t)
$1 = 2

 

 

示例2:想知道某个成员的在结构体中的偏移,如想知道struct worker结构体中成员worker.flags的偏移,可以使用gdb如下方式获取:

(gdb) p &(((struct worker*)0)->flags)
$14 = (unsigned int *) 0x68 <irq_stack_union+104>

这个操作原理是借鉴内核container_of来实现的.

posted on 2021-06-17 21:34  温暖的电波  阅读(966)  评论(0编辑  收藏  举报