不只是越界——泄漏、非法释放、未使用、未对齐一网打尽

举报
黄生 发表于 2026/09/17 20:48:56 2026/09/17
【摘要】 系列二 · 第 4 篇上篇认识了影子内存,它管的是"某个字节现在能不能碰"。但内存问题还有另一半:生命周期。一块 GM 什么时候申请的、该谁释放、到底用没用过——这些"时间线"上的问题,得靠另一套台账来盯。msSanitizer 里负责记账的是堆块管理器(HeapBlockManager)。它干的事特别像小区物业:每一次 malloc 登记一笔"谁、多大、在哪",每一次 free 找对应的登...

系列二 · 第 4 篇

上篇认识了影子内存,它管的是"某个字节现在能不能碰"。但内存问题还有另一半:生命周期。一块 GM 什么时候申请的、该谁释放、到底用没用过——这些"时间线"上的问题,得靠另一套台账来盯。

msSanitizer 里负责记账的是堆块管理器(HeapBlockManager)。它干的事特别像小区物业:每一次 malloc 登记一笔"谁、多大、在哪",每一次 free 找对应的登记销账。就在这"登记—销账"之间,三种经典 bug 自己浮了出来。

如果 free 的时候翻半天账本找不到这笔记录——要么地址是假的,要么这笔已经释放过一遍了,这就是非法释放(illegal free)。如果程序跑完,账本上还摊着一堆没销掉的记录——这些内存从登记到终场都没人释放,就是内存泄漏(leak)。如果一笔内存在整个生命周期里登记了、也释放了,但中间一次都没被访问过——白占地方,就是"分配但未使用"。

那越界又怎么查?它靠的其实是一张"已分配区间表",源码里叫 BoundsCheck。别和影子内存搞混了:影子内存记状态,区间表记边界。每次访问,工具拿地址去区间表里比对,落在哪段已分配的区间内,就算合法;落在区间外面的字节数,就是越界的量。GM 的区间零散、还带读写权限,就用一种能合并、能切分的离散区间结构来管;UB、L1 这些片上空间每块大小固定,直接当一整个区间看,简单粗暴但管用。

还剩一条"未对齐"(misaligned)。昇腾的片上存储有对齐要求,地址不对齐的访问效率低甚至非法。这条最好查:拿访问地址对对齐大小取模,余数不为零就报警。所以工具把它单独拎成一个 AlignChecker,几乎不占多少逻辑,却常常最早上报。

看到这你会发现,内存检测其实是一堆小机制的分工协作:影子内存看状态,堆块台账看生命周期,区间表看边界,对齐检查看地址规整。为了不把这堆逻辑糊成一团,源码把它们抽象成几个统一动作——malloc、free、load、store,再算上内存拷贝,各干各的那份活,主流程清清爽爽。这种"策略模式"的拆法,后面聊架构时还会再见。

最后打个预防针。源码里有个枚举名叫 OUT_OF_BOUNDS,别被名字骗了——它查的其实是"多核踩踏",不是普通越界;普通越界叫 ILLEGAL_ADDR_READ / ILLEGAL_ADDR_WRITE。这个命名坑,正好引出下一篇的主角:多核踩踏。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。