结构体指针初始化slab分配器失败:内存赋值不生效
问题排查与解决
1. 页内存无写权限
mapKernelPage分配的页可能默认仅映射为只读权限,导致所有赋值操作无法生效,内存始终保持初始的0x00状态。
- 验证:检查
mapKernelPage的实现,确认是否在映射时设置了可写属性(比如x86架构的PTE_PW位、ARM架构的AP权限位)。 - 修复:调用
mapKernelPage时显式指定可写权限,或在分配后修改页表项添加写权限。
2. slab4perPage计算错误
结构体slabAlloc4_t带有__attribute__((packed))属性,需先计算其实际大小:
// 32位系统下总大小 = 4(uint32_t) + 4(指针) + 2(uint16_t) + 128(availmap) = 138字节 // 4096字节页可容纳的实例数:4096 / 138 = 29(整数除法取整)
如果slab4perPage的值大于实际可容纳的数量,循环中temp++会越界到当前页之外,修改的内存并非目标页内容,导致页内始终为0。
- 验证:打印
sizeof(struct slabAlloc4_t)和slab4perPage的值,确认slab4perPage等于4096 / sizeof(struct slabAlloc4_t)(整数除法取整)。 - 修复:修正
slab4perPage的计算逻辑,确保不超过页内可容纳的最大实例数。
3. mapKernelPage返回无效地址
如果mapKernelPage分配失败,返回了NULL或错误的虚拟地址,后续对temp的赋值操作都是在非法内存上进行,不会影响目标页。
- 验证:在分配后立即检查
slab4是否为NULL,或打印其地址是否在合法的内核虚拟地址范围内。 - 修复:排查
mapKernelPage的实现,确认页分配和映射逻辑正确,确保返回有效的可访问虚拟地址。
4. 内存对齐或指针类型不匹配
如果是64位系统,结构体中的nextaddr指针是64位,但__attribute__((packed))会取消对齐,可能导致指针存储位置不对齐,赋值时出现异常或写入错误位置。
- 验证:检查编译环境是32位还是64位,确认结构体指针的大小与系统位数匹配。
- 修复:如果是64位系统,确保结构体定义符合指针长度要求,或去掉
packed属性(若允许内存对齐)。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

