kfree源码分析(如何确定obj的cache)


思维导图

源码分析

先看Linux-5.10的源码:https://elixir.bootlin.com/linux/v5.10/source/mm/slub.c#L4103

这里的page = virt_to_head_page(x)获取的是x所在页的page_struct;

然后由于slab是page的复用,所以直接通过page->slab_cache就能找到对应的kmem_cache;

然后进入到slab_free函数中:

首先是slab_free_freelist_hook函数:

问题分析

笔者在实践中发现一个问题:当调试kfree的时候,刚进入kfree即查看其obj的page,发现其slab_cache竟然是一个非法地址0xdead000000000400:

然后跟进到具体执行过程中,其page是在这个位置被加载到rbp寄存器中的(好多inline函数):

查看仍然是非法地址:

发现到了下面这个位置会根据rax的标志将rbp换成rdx:

这个rdx的味道就对了:

观察发现两个的地址差距并不大,仅仅差距0x180,也就是6个page的大小,看看这个rdx是从哪里来的:

笔者结合调试结果(这个obj来自于kmalloc-4k)进行分析,大概是由于这个obj所在的slab很大(8个页大小),所以不是每一个page结构体都能充当slab结构的,只有第一个页的page可以,所以就要用偏移为8的这个成员的最低的一位来表示该页是不是首页,如果不是,就要去掉这个位之后索引到首页的page结构体,这才是真正的slab。


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录