news 2026/10/29 2:08:32

slub init_object

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
slub init_object

init_object()是 SLUB 调试里用于初始化对象内存内容的函数,把对象的有效数据区填成指定字节,用于 poison 机制。

一、函数签名

static void init_object(struct kmem_cache *s, void *object, u8 val)
参数含义
s缓存
object对象指针
val要填充的字节值

无返回值。

二、典型实现

static void init_object(struct kmem_cache *s, void *object, u8 val) { u8 *p = object; if (s->flags & SLAB_RED_ZONE) memset(p - s->red_left_pad, val, s->red_left_pad); if (slub_debug_orig_size(s) && val == SLUB_RED_INACTIVE) { /* 对象未使用,不填充有效数据区 */ return; } if (s->flags & SLAB_POISON) memset(p, val, s->size - s->red_left_pad); }

具体条件随版本有差异,但核心动作是:

  1. 填左红区:若开启SLAB_RED_ZONE,把对象前面的左红区填成val。

  2. 填对象数据区:若开启SLAB_POISON,把对象有效数据区填成val。

  3. 可能跳过 orig_size 区域:避免覆盖 orig_size 元数据。

三、val的取值:poison 字节

val由调用者传入,通常来自内核定义的 poison 常量:

常量值含义
POISON_FREE0x6b('k')对象空闲时填充,表示“已释放,可用”
POISON_INUSE0x5a('Z')对象使用中填充,检测未初始化读
SLUB_RED_INACTIVE0xbb红区未激活(正常)填充
SLUB_RED_ACTIVE0xcc红区激活(已分配)填充

两种典型调用

分配时:对象从空闲变已分配,先填POISON_INUSE:

// alloc_debug_processing init_object(s, object, POISON_INUSE);

释放时:对象从已分配变空闲,填POISON_FREE:

// free_debug_processing init_object(s, object, POISON_FREE);

四、poison 机制的检测原理

分配时填 0x5a 0x5a 0x5a ... │ ├─ 用户正常使用,写入数据,覆盖 0x5a │ ├─ 若某处读到仍是 0x5a → 说明“使用了未初始化内存” │ └─ 释放时填 0x6b 0x6b 0x6b ... │ ├─ 若之后又读到 0x5a 或其他值 → 说明“释放后被写”(use-after-free) │ └─ 若释放时发现还是 0x5a 原样 → 说明“对象从未被使用过”(可能泄漏)

init_object()就是打上这些标记的写入端。

五、红区填充

if (s->flags & SLAB_RED_ZONE) memset(p - s->red_left_pad, val, s->red_left_pad);
  • p - s->red_left_pad:对象真实起点(含左红区)。

  • 填red_left_pad字节。

  • 右红区通常由其他逻辑填充(如set_redzone)。

  • 红区正常应保持特定值,若被改写说明越界写。

六、使用场景

init_object()在调试路径中成对出现:

// 分配:标记为“使用中” static int alloc_debug_processing(struct kmem_cache *s, struct slab *slab, void *object, unsigned long addr) { ... init_object(s, object, POISON_INUSE); set_track(s, object, TRACK_ALLOC, addr, GFP_ATOMIC); ... } // 释放:标记为“空闲” static int free_debug_processing(struct kmem_cache *s, struct slab *slab, void *object, unsigned long addr) { ... init_object(s, object, POISON_FREE); set_track(s, object, TRACK_FREE, addr, GFP_ATOMIC); ... }

配合check_object()校验:

// check_object 发现 poison 值不符 → 报告 use-after-free 或未初始化使用 if (s->flags & SLAB_POISON) { if (val != POISON_FREE && val != POISON_INUSE) { object_err(s, slab, object, "Poison overwritten"); } }

七、门控与零开销

  • 未开SLAB_POISON且未开SLAB_RED_ZONE:两个if都不成立,函数什么都不做。

  • 未编译CONFIG_SLUB_DEBUG:整个函数可能不编译或退化为空。

  • static:仅本文件内使用,编译器可内联或消除。

  • 生产内核里init_object()调用点可能直接不执行,零开销。

八、与前面知识的呼应

前面讲过这里体现
SLAB_POISON控制对象数据区填充
SLAB_RED_ZONE控制左红区填充
red_left_pad左红区大小
POISON_FREE/POISON_INUSEval的典型取值
check_object()校验 poison 是否被破坏
set_orig_size()可能与init_object配合,避免覆盖 orig_size
print_trailer()出错时打印 poison 区域内容

九、一句话总结

init_object(s, object, val)把对象的左红区和有效数据区填成指定 poison 字节val:分配时填POISON_INUSE(0x5a)标记“使用中”,释放时填POISON_FREE(0x6b)标记“已空闲”。它是 SLUB poison 机制的写入端,配合check_object()检测未初始化使用、use-after-free、越界写,未开SLAB_POISON/SLAB_RED_ZONE时零开销。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 2:07:22

QByteArray 详解:既是二进制字节数组,也能拥有类 QString 的文本 API

QByteArray 详解:既是二进制字节数组,也能拥有类 QString 的文本 API1、引言:一个被低估的类2、 QByteArray 是什么2.1 、基本定位2.2、 与 QString 的关系3、创建与初始化4、 二进制视角:真正的字节数组4.1、 追加与访问原始字节…

作者头像 李华
网站建设 2026/10/29 2:06:52

模型越强,越需Agent落地

尽管大模型(LLM)的推理、多模态理解及泛化能力确实在飞速提升(如字节 Seed1.5-VL 等多模态模型的发布,显著增强了 AI 对视觉和复杂现实世界的理解能力),但这反而加剧了开发 Agent 的必要性,而非…

作者头像 李华
网站建设 2026/10/29 2:06:32

设备上云联调熬3天?C#工控机MQTT对接阿里云/华为云工业平台全链路实战

做过工业设备上云的开发者,大概率都有过这种崩溃经历: 客户要求把产线数据接到阿里云工业互联网平台,本以为就是MQTT发个JSON的事,半天就能搞定。真上手才发现坑一个接一个:设备认证要一机一密、数据要符合物模型格式、断网了不能丢数据、平台还要能反向下发控制指令,连消…

作者头像 李华
网站建设 2026/10/29 2:05:52

ReAct大模型推理模式详解:小白也能学会,收藏这份高效指南!

本文深入解析了CoT、ReAct、ToT三种大模型推理模式的原理与应用场景,指出80%的Agent任务仅需ReAct即可满足需求,ToT虽效果提升有限但成本高昂。文章强调选择推理模式需根据任务推理步骤数与路径唯一性,并提供决策路径图帮助读者快速选型&…

作者头像 李华