Linux 内存管理之 SLUB分配器(6):slub debug 实例测试

Linux 内存管理之 SLUB分配器(6):slub debug 实例测试

1. Object layout

slub object layout 之前已经有专门的一小节进行介绍了,这里直接将其结果拿来:

image-20220110205909589

2. 配置开关

默认情况下上述的layout中debug信息是没有打开的,毕竟会增加太多的内容,增加内存的压力,所以需要打开如下部分内容:

  1. Config:

    CONFIG_SLUB=y

    CONFIG_SLUB_DEBUG=y

    CONFIG_SLUB_DEBUG_ON=y

    CONFIG_SLUB_CPU_PARTIAL=y

  2. kernel cmd:

    bootargs 中添加slub_debug=UFPZ

这部分内容的目的就是打开debug开关,将我们申请的object配置为上述图示的样子

3. 实例测试

一般来讲我们常见的内存问题,主要包含如下几个类别:

  1. 内存越界
    1. 左侧越界
    2. 右侧越界
  2. 未申请内存即使用
  3. 释放后使用
    1. 重复释放
    2. 释放后使用

3.1 内存越界

任意找一个可以运行的驱动,申请一个buf,进行赋值即可:

image-20220110211223899

分段分析运行结果:

  1. 错误类型提示打印:Redzone overwritten

    (220110_11:38:07.257)[ 20.693618]<1>E=============================================================================
    (220110_11:38:07.257)[ 20.693622]<1>EBUG kmalloc-128 (Tainted: G B ): Redzone overwritten
    (220110_11:38:07.257)[ 20.693623]<1>E-----------------------------------------------------------------------------

    由于此case为越界检测,在object中实际分配空间的两侧,均被标记为redzone,所以这里看到的是 Redzone overwritten

  2. 问题object打印:First byte 0x23 instead of 0xcc

    image-20220110211953192

    这里有告诉我们是哪一个object,地址和偏移是怎样的,发生了怎样的错误,这里是检测到应该为0xcc的数值被写为了0x23,所以认为发生了越界;

  3. object layout的实际打印:

    image-20220110212237082

    对比这张图来看:

    image-20220110212318525

    很明确,左侧redzone被篡改

  4. 调用堆栈打印:

    image-20220110212511249

    这里有两个点需要注意:

    • 检测是在alloc或者free时进行,即我们篡改后当时是没有主动上报信息的;
    • 检测到异常后会将该值修复,即将0x23修复为0xcc,并将信息打印;

以上即为内存越界,左侧越界的测试和信息打印;

3.2 重复释放

与上述测试相同,我们申请一块buf,释放两次,code如下:

image-20220110212844625

测试结果与上述内存越界形式基本相同,在内容上有些许差异:

  1. 错误类型:Object already free

    image-20220110213236557

  2. 问题object打印:

    image-20220110213328113

  3. object layout的实际打印:注意被释放后redzone中为bb,实际空间内容为6b

    image-20220110213406137

  4. 调用堆栈打印:

    image-20220110213508553

3.3 释放后使用

image-20220110212907160

  1. 错误类型:Poison overwritten

    image-20220110213555341

  2. 问题object打印:被释放后object空间应该为0x6b,而这里我们将其修改为0x11,被检测到;

    image-20220110213710981

  3. object layout的实际打印

    image-20220110213808104

  4. 调用堆栈打印:

    image-20220110213902108

上述几个case的话,基本上可以看到存在异常时的信息打印形式,其检测依据就是我们开篇的那个图,另外这里有个缺陷是相关检测都是在alloc和kfree时进行的,即在错误发生时并不会打印内容;

4. 核心API

检测逻辑:

image-20220110214340192

会依次检测到slab、pointer、object,上述几个例子都是object的类型;

image-20220110214641247

check object中即会依次检查red zone和poison

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内存管理中的页面分配器是负责分配和管理物理页面(Page)的一种机制。在内核中,物理页面是以固定大小的块进行管理的,通常被称为页面帧(Page Frame)。页面分配器的主要任务是从可用的物理内存中分配页面帧,并在需要时释放这些页面帧。 Linux中有多种页面分配器,其中最常用的是伙伴系统(Buddy System)。伙伴系统将可用的物理内存划分为不同大小的块,每个块都是2的幂次方大小。当需要分配一块n个页面帧大小的内存时,伙伴系统会找到一个大小为2的幂次方,并且大于等于n的最小块。如果找到的块大于n,则将该块分裂成两个小块,其中一个块将被分配,另一个块将被留作备用。如果找到的块恰好是n,则将该块分配出去。如果没有合适的块可用,则会尝试从内存中释放一些页面帧来获得可用的内存。 伙伴系统的优点是效率高,分配和释放内存的速度都很快。它还可以避免内存碎片的问题,因为它只分配大小为2的幂次方的块,这些块可以非常有效地组合在一起,而不会留下任何碎片。但是,伙伴系统的缺点是它会浪费一些内存。当一个块被分割成两个小块时,其中一个块可能永远不会被使用,从而浪费了一些内存。 除了伙伴系统之外,Linux还提供了其他的页面分配器,如SLAB和SLUB。这些页面分配器适用于不同的场景,具有不同的优缺点。在实际应用中,应该根据具体的需求选择适合的页面分配器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值