Mac/iOS 野指针&内存不足问题&内存碎片问题分析

举报
dosomething 发表于 2023/12/05 18:57:39 2023/12/05
【摘要】 观看此篇文章前需掌握理论知识:https://bbs.huaweicloud.com/blogs/417232野指针问题故名思意,野指针问题就是指针指向了一个已经释放的内存块,系统是如何检测到野指针问题的呢,下面举例说明1、初始状态,p1、p2指向了slotK+1,当前block的meta已经有指向的内容(有释放)2、free(p1),slotK+1的内容变成了结构体nanov2_free_...

观看此篇文章前需掌握理论知识:https://bbs.huaweicloud.com/blogs/417232

野指针问题

故名思意,野指针问题就是指针指向了一个已经释放的内存块,系统是如何检测到野指针问题的呢,下面举例说明

1、初始状态,p1、p2指向了slotK+1,当前block的meta已经有指向的内容(有释放)

d (8).png

2、free(p1),slotK+1的内容变成了结构体nanov2_free_slot_t,guard内容为当前slot的指针 ^ nanozone.cookie,next_slot指向了slotN

d (9).png

3、访问p2,此时如果是读取数据,slok+1的数据已经不是原有数据,读取没有任何意义,但是不会崩溃

写入p2,会破坏nanov2_free_slot_t结构体,此时并不会异常。

d (10).png

4、用户malloc新的内存,如果刚好返回的是slotK+1,系统会首先校验slotK+1的guard,如果异常会报

image.png

怎么校验呢:

guard ^ cookie = ptr;,不满足则异常

思考:如何让p2在写入时就报异常呢?

措施:

1、申请内存时: 在申请的内存前面写上size,并返回size占内存的偏移

d (11).png

这样如果在申请后发生越界,则可以直接通过前缀判断出越界问题。

2、内存释放后,数据段前面写入特殊flag

d (12).png

这时候如果访问p时,p的前缀为flag,则代表发生野指针问题。

其实苹果有相应功能的开关。只需要打开即可

Malloc Scribble:malloc时将内存全部变为0xaaaaa...,释放后变成0x5555,效果不明显,用处不大

Guard Malloc:malloc的内存前缀加上0xdeadbeefdeadbeef,释放后前缀删掉,只要没有此前缀的内存访问都会异常

Address Sanitizer:原理更复杂,释放后的地址会被标记为poisoned,释放后访问会被检测到并崩溃

应用场景更广:

  1. Use after free
  2. Heap buffer overflow
  3. Stack buffer overflow
  4. Global buffer overflow
  5. Use after return,
  6. Use after scope
  7. Initialization order bugs
  8. Memory leaks

内存不足问题

有时候会报内存不足问题,但是实际上可以看到还有100mb左右的内存,为什么会报内存不足呢?

通过nano内存管理篇的学习,我们清楚了内存是分级的,特别对iOS来说,只有1个region,那么16B内存只有2MB,超过了2MB就会报内存不足。

image (1).png

因此,在使用内存时要合理的分配

内存碎片

结合nano内存的分析可知,如果故意构建每个block都只保留1个slot,则会导致大范围的内存碎片,所以尽量的增大Blocks中绿色slot的部分,可以降低内存碎片

d (13).png

Xcode导出memgraph文件,文件中包含了内存碎片相关内容

vmmap -summary *.memgraph

image (2).png

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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