首页 > 系统相关 >内存管理——内存调试技术

内存管理——内存调试技术

时间:2022-08-31 12:00:22浏览次数:78  
标签:技术 guard tag 内存 memory ASAN byte 调试

常见内存问题

内存问题有两种:内存损坏 memory corruption(crash) 和 内存泄漏 memory leak

memory crash:发生在修改了未知内存后,程序访问了这部分受损的内存,可能会导致程序crash掉或者发生不可预知的结果。

发生在:

  • 使用未初始化的内存
  • 使用不存在的内存,空指针
  • 使用了超出分配的内存,数组越界
  • 堆内存管理错误,UAF,double free

memory leak:动态分配的内存没有释放,或者分配太多内存跑不到free的地方

可能会引起:

  • 程序功能正常,但是引起系统性能卡顿,apk越来越慢
  • 内存泄漏过多导致申请内存不足malloc mmap失败,造成OOM等其他问题

内存调试技术

Malloc Debug

Malloc debug 是一种native层内存问题的方法。他可以帮助我们定位memory crash, memory leak, UAF的问题。如果检测到任何的问题,会通过日志的方式呈现出来。

Malloc Debug 开启后会在替换掉原来的内存分配函数(加Hook层),在分配的内存数据前加Header,并且可以根据option添加前后的front_guard和rear_guard。

Header
front_guard
allocation data
rear_guard

Header组成如下:

struct Header {
    uint32_t tag;		//标记内存是否释放
    void* orig_pointer;	//指向Header的起始地址
    size_t size:		//allocation data的大小
    size_t usable_size; //已使用大小
}__attribute__((packed)); //取消内存对齐

在Header中有个tag标记内存是否释放:0x1ee7d00d为可以使用, 0x1cc7dccd为已经释放

  • front_guard 由 0xaa 填充的8个byte组成
  • rear_guard 由 0xbb 填充的8个byte组成

根据这些前后的固定填充,如果这些固定的字节发生了变化可以判断这部分内存被踩了。

相关的option:

  • guard 可以开启front_guard和rear_guard,做越界检查
    • 不会在写超的时候第一现场拦下来,只有free的时候才可以检查
  • free_track 可以检查UAF
    • 当free后不会归还系统,而是保存到List,填充内容为0xef。如果后面发现这部分内容不是0xef的话就表示这部分内存UAF了
    • 但是这样会有额外内存开销,系统压力会比较大。
  • backtrace 追踪每次分配信息
    • 会大大减慢内存分配的速度。如果因为开启这个选项导致系统运行太慢,需要减少采集的帧数。

通过 dump + gdb 查看内存信息。
malloc debug 对内存调试有帮助,但是不方便,你只能确定发生了这些问题,但是不能在第一现场拦下,也不能确定问题发生的时间。

ASAN

ASAN:Address Sanitizer Mechanism

把进程虚拟地址分成两部分,一部分是正常使用的main application memory,一部分是Shadow memory影子内存,两者占比8:1。

shadow memory用来记录main allocation memory的状态。

这个debug方法可以在第一现场拦下

但是ASAN只能标记内存能否访问,没有标记内存的所有者。

log里面会把出错的report打印出来

开启方式:make结束以后再执行一次相应的命令

HWASAN

HWASAN:Hardware ASAN

需要在64位机器上,并且要内核4.14以上才支持

可以标记内存的所有者,在指针的最高2byte做了tag

HWASAN可以检测的bug与ASAN相同:

  • 堆栈buffer溢出
  • UAF,double free
  • 栈溢出

与ASAN的改动:main application memory 与 shadow memory 的占比为16:1

然后在可用内存地址的最高2个byte(16个bit)加了个tag标记内存所有者

在shadow memory如果对应的main memory的16个byte都可以访问,则shadow memory存放tag的值,如果只有部分byte可以访问,则记录0~15可访问的byte,然后将tag的值记录到main memory最后一个不可访问的byte上。

开启方式:可以用一次make指令然后加上编译选项即可: make SANITIZE_TARGET=hwaddress

如何确认已开启?通过ps | grep process找到进程号,然后cat /proc/pid/maps|grep hwasan

缺点:因为tag只有8bit,最多只有256个不同的tag,有概率会分配2个相同的tag

Slub Debug

用于内核层的debug工具,与Malloc Debug类似采用前后插guard的方式

KASAN

对应与用户空间的ASAN工具。也是采用shadow memory来检测内存,占可用内存的1/8,会带来内核内存空间的开销。

开启方式:在.config配置文件中指定 CONFIG_KASAN_GENERIC=y

KASAN有三种,GENERIC KASAN, Software Tag-based KASAN, Hardware Tag-based KASAN

memory leak

cat /proc/meminfo 查看内存使用情况
cat /proc/pid/maps 查看进程的内存映射情况(比如使用malloc后会出现[heap]区

标签:技术,guard,tag,内存,memory,ASAN,byte,调试
From: https://www.cnblogs.com/Ethan-Code/p/16642440.html

相关文章

  • .Net Core调试Liunx
    场景:之前做.netcore项目,只能本机调试测试完,发布后放在liunx上。但这个时候经常会因为环境问题,配置问题等,导致程序出现莫名其妙的bug,有的日志还记录的不完善,很难找到......
  • 侯捷 内存管理 笔记pdf
    https://www.zhihu.com/people/xu-wei-duan-ke/posts    <<侯捷C++内存管理第二讲笔记(二)-知乎.pdf>>  <<侯捷C++内存管理第一讲笔记-知乎.pdf>> ......
  • 关于分布式全内存数据库RapidsDB主要应用场景?
    分布式全内存数据库RapidsDB主要应用场景包含以下四项:一是大数据平台快速数据检索、分析及计算处理的需求;二是基于磁盘存储的数据库受限于磁盘读写速度,很难满足业务系统低......
  • 编译技术:练习1
    1解释下列名词术语:源程序、目标程序、翻译程序、汇编程序、编译程序、解释程序、遍。【解答】源程序:符合某特定语言(称为源语言)的规则的程序文本,一般由高级语言或汇编语......
  • 对团队规范和技术的几点总结
    这两天团队要做项目总结,所以个人就浅薄的作了几点总结,当然,是从团队研发人员的角度去出发,因为团队的研发人员是基石,是铸造项目和产品的核心,产品的质量完全由研发人员来决定......
  • 如何从数据科学技术中获得最大价值?
    如何从数据科学技术中获得最大价值?PhotobyLukeChesseron不飞溅真正的数据科学问题具有其自身的特殊特征或特征,需要以自己的顺序或方式解决。将相同的技术应用于......
  • MATLAB中的“内存不足”?使用此技巧可轻松将内存使用量减半
    MATLAB中的“内存不足”?使用此技巧可轻松将内存使用量减半我将演示如何简单地更改数字数据的精度可以将内存使用量减少一半甚至更多Photoby拥有摄影on不飞溅H您......
  • 从汇编看C++类的内存Layout(3)
    本文主要从汇编的角度,看C++类的内存模型,即C++类的各种数据是如何分布的。1.假设有如下Cpp文件:classMemoryLayout.cppclassBase{public:Base(){}......
  • ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("Id",getId())防止内
    publicStringtoString(){returnnewToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE).append("Id",getId()).append("AdClientId",getAdClientId()).appe......
  • 02.XML技术
    一、XML简介XML指可扩展标记语言(eXtensibleMarkupLanguage),是用来传输和存储数据的,是一种通用的数据交换格式,可以使数据在不同应用程序间交换,具有很强的可扩展性。 ......