slub init_tracking init_tracking()是 SLUB track 机制的初始化函数在一个对象首次分配出去之前把它内部的struct track槽位清零避免残留的旧追踪信息造成误判。一、函数签名static void init_tracking(struct kmem_cache *s, void *object)参数含义s缓存object对象指针无返回值。二、典型实现static void init_tracking(struct kmem_cache *s, void *object) { if (!kmem_cache_debug_flags(s, SLAB_STORE_USER)) return; memset(get_track(s, object, TRACK_ALLOC), 0, sizeof(struct track)); memset(get_track(s, object, TRACK_FREE), 0, sizeof(struct track)); }逻辑门控检查未开SLAB_STORE_USER直接返回。清零分配 trackget_track(s, object, TRACK_ALLOC)定位到分配槽位memset清零。清零释放 track同样清零释放槽位。两个struct track全部置零表示“尚无分配/释放记录”。三、为什么需要初始化struct track存在对象元数据区随着 slab 页的分配和复用这块内存会残留上一次对象生命周期的追踪数据。如果不初始化伪造历史新对象还没分配get_track()却读到旧对象的addr、pid、when调试时误以为“这个对象曾被某进程分配过”。误判 use-after-free释放检查可能读到旧记录得出错误结论。统计错误基于 track 的统计如存活时长会算出离谱的值。所以对象首次进入可用状态时必须把 track 区清零。四、调用时机init_tracking()在新 slab 页初始化、对象首次被分配之前调用。典型位置// 在 allocate_slab / new_slab 之后建立 freelist 前后 static struct slab *allocate_slab(...) { ... for_each_object(p, s, addr, slab-objects) init_tracking(s, p); // 每个对象都初始化 ... }或在新对象从 freelist 取出、真正交付给用户之前// alloc_debug_processing 里 if (unlikely(!alloc_debug_processing(s, slab, object, addr))) goto out; // alloc_debug_processing 内部 set_track(s, object, TRACK_ALLOC, addr, gfp_flags); // 在此之前 track 应为已初始化状态具体位置随版本不同但语义一致在写入第一条 track 记录之前保证槽位是干净的。五、与set_track/get_track的关系新 slab 页 / 新对象 │ ├─ init_tracking(s, object) // 清零 track[ALLOC] 和 track[FREE] │ ├─ 分配时set_track(..., TRACK_ALLOC, ...) // 写入分配记录 │ ├─ 释放时set_track(..., TRACK_FREE, ...) // 写入释放记录 │ └─ 调试读取get_track(..., TRACK_ALLOC/FREE) // 读回记录函数阶段操作init_tracking初始化清零两个 trackset_track分配/释放写入对应 trackget_track调试读取定位并返回 track 指针三者构成完整生命周期清零 → 写入 → 读取。六、性能考量门控未开SLAB_STORE_USER直接返回零开销。只在 slab 初始化时调用不是每次分配都调用频率低。memset两个struct track大小约 28~152 字节取决于CONFIG_STACKDEPOT相比分配路径其他开销可接受。调试专用生产内核不编译这段逻辑。七、与前面知识的呼应前面讲过这里体现struct track被清零的对象get_track()定位 track 槽位TRACK_ALLOC/TRACK_FREE两个槽位SLAB_STORE_USER门控条件kmem_cache_debug_flags()检查标志set_track()写入端init_tracking初始化端写入前清场八、一句话总结init_tracking(s, object)在开启SLAB_STORE_USER时把对象的track[TRACK_ALLOC]和track[TRACK_FREE]两个struct track清零确保对象首次分配前没有残留的旧追踪信息是 SLUB track 机制“清零 → 写入 → 读取”生命周期的第一步。