1、关于AddressSanitizer

1.1 引言

也许很多人都听说过类似这样的一个故事:某公司的服务器每隔3个月就会毫无预兆的崩溃一次,怎么也查不出原因,为了避免崩溃可能引发的问题,只得每2个月手动重启一次服务器。在这类有些灵异的事件背后,以内存泄露为代表的一系列内存错误往往就是那个幕后黑手。

在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

内存泄漏会导致可用内存的数量减少从而降低计算机的性能。过多的可用内存被分配掉会导致全部或部分设备停止正常工作,或者应用程序崩溃。

其他的内存错误还包括缓冲区溢出、越界访问等,此类错误轻则导致程序计算错误,重则引起程序崩溃,在内存紧张的嵌入式系统中尤为致命,Google旗下的开源工具AddressSanitizer可以帮助我们检测此类错误。

AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。它包括一个编译器instrumentation模块和一个提供malloc()/free()替代项的运行时库。从gcc 4.8开始,AddressSanitizer成为gcc的一部分。

详细了解AddressSanitizer信息可以访问其github项目地址:
https://github.com/google/sanitizers/wiki/AddressSanitizer

1.2 AddressSanitizer原理简介

AddressSanitizer主要包括两部分:插桩(Instrumentation)和动态运行库(Run-time library)。插桩主要是针对在llvm编译器级别对访问内存的操作(store,load,alloca等),将它们进行处理。动态运行库主要提供一些运行时的复杂的功能(比如poison/unpoison shadow memory)以及将malloc,free等系统调用函数hook住。该算法的思路是:如果想防住Buffer Overflow漏洞,只需要在每块内存区域右端(或两端,能防overflow和underflow)加一块区域(RedZone),使RedZone的区域的影子内存(Shadow Memory)设置为不可写即可。具体的示意图如下图所示。

内存映射

AddressSanitizer保护的主要原理是对程序中的虚拟内存提供粗粒度的影子内存(每8个字节的内存对应一个字节的影子内存),为了减少overhead,采用了直接内存映射策略,所采用的具体策略如下:Shadow=(Mem >> 3) + offset。每8个字节的内存对应一个字节的影子内存,影子内存中每个字节存取一个数字k,如果k=0,则表示该影子内存对应的8个字节的内存都能访问,如果0<k<7,表示前k个字节可以访问,如果k为负数,不同的数字表示不同的错误(e.g. Stack buffer overflow, Heap buffer overflow)。

插桩

为了防止buffer overflow,需要将原来分配的内存两边分配额外的内存Redzone,并将这两边的内存加锁,设为不能访问状态,这样可以有效的防止buffer overflow(但不能杜绝buffer overflow)。以下是在栈中插桩的一个例子。

未插桩的代码:

插桩后的代码:

插桩后的代码:

在动态运行库中将malloc/free函数进行了替换。在malloc函数中额外的分配了Redzone区域的内存,将与Redzone区域对应的影子内存加锁,主要的内存区域对应的影子内存不加锁。
free函数将所有分配的内存区域加锁,并放到了隔离区域的队列中(保证在一定的时间内不会再被malloc函数分配),可检测Use after free类的问题。
详细了解ASan算法原理可以访问以下地址:
https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm

2、使用方法

环境:Ubuntu 16.04   gcc 4.8以上
用-fsanitize=address选项编译和链接你的程序;
用-fno-omit-frame-pointer编译,以在错误消息中添加更好的堆栈跟踪。
增加-O1以获得更好的性能。
下面以简单的测试代码leaktest.c为例

在终端中输入以下命令编译leaktest.c

运行leaktest,会打印下面的错误信息:

第一部分(ERROR),指出错误类型detected memory leaks;
第二部分给出详细的错误信息:Direct leak of 80 byte(s) in 1 object(s),以及发生错误的对象名/源文件位置/行数;
第三部分是以上信息的一个总结(SUMMARY)。

3、设置检测白名单

可以根据以下的需求设置ASan检测白名单
忽略一个确定正确的函数以提高应用运行速度;
忽略一个特定功能的函数(例如:绕过框架边界穿过线程的堆栈);
忽略已知的问题。

使用no_sanitize_address属性(Clang3.3及GCC4.8以上版本支持)定义如下的宏命令:

4、AddressSanitizer能检测的错误类型(以官方Wiki为准)

文章原地址: https://www.bynav.com/cn/resource/bywork/healthy-work/70.html?id=35

AddressSanitizer使用介绍相关推荐

  1. 内存泄漏查找工具----valgrind简介与使用

    目录 1 valgrind简介 2 常用参数 3 使用示例 用了一下asan,感觉比valgrid好用,以后用asan,asan的使用方法内存错误分析工具----asan(AddressSanitiz ...

  2. gcc:内存问题检查选项 -fsanitize; asan

    文章目录 简介 参考 详细介绍 编译时依赖 实例 内核里的检查是使用kasan -fsanitize=object-size Linux 内核相关 简介 如果可以用这个工具,其实很大程度上方便了开发者 ...

  3. valgrind 内存泄漏_应用 AddressSanitizer 发现程序内存错误

    应用 AddressSanitizer 发现程序内存错误 作为 C/ C++ 工程师,在开发过程中会遇到各类问题,最常见便是内存使用问题,比如,越界,泄漏.过去常用的工具是 Valgrind,但使用 ...

  4. 内存检测_Android native内存检测工具介绍

    点击上方蓝字关注我们噢~ 检测工具不仅可以在验证时发现安全问题,也可以在运用场景中阻断安全问题的发生,对于安全问题检测和攻击拦截非常友好,当然安全检测功能会消耗一定的系统性能.本文将对已集成的部分检测 ...

  5. PX4开源工程结构简明介绍

    PX4开源工程结构简明介绍 Step1 获取开源代码 1.1 开源代码版本 1.2 克隆开源代码 Step2 了解工程情况 2.1 支持模型类型 2.2 支持特性&功能 2.3 安装& ...

  6. AddressSanitizer 页面

    介绍 AddressSanitizer 是一个快速的内存错误检测工具,它由一个编译时插桩模块和一个运行库组成.该工具可以检测以下类型的错误: OOB(包括堆.栈和全局变量) UAF Use-After ...

  7. 使用Clang作为编译器 —— AddressSanitizer

    AddressSanitizer(未完成) 1. 介绍 2. 如何构建 3. 使用(Usage) 4. 用符号表现报告(Symbolizing the Reports) 5. 额外的检查(Additi ...

  8. 应用 AddressSanitizer 发现程序内存错误

    应用 AddressSanitizer 发现程序内存错误 作为 C/ C++ 工程师,在开发过程中会遇到各类问题,最常见便是内存使用问题,比如,越界,泄漏.过去常用的工具是 Valgrind,但使用 ...

  9. AFL++ (PlusPlus) 介绍与实践

    文章目录 一.AFL++简介 缝合块 AFL基础款 1 基于覆盖率指标的反馈 2 变异 3 fork 服务器 基于智能调度的加强版 1 AFLFast 2 MOpt 基于绕过障碍的加强版 1 [LAF ...

最新文章

  1. 工资高低由什么决定?(面试时如何谈工资?工作中怎样做才能不断涨工资?)...
  2. unity 让一个数按一秒累加_unity中的数据储存读取(基于PlayerPrefs)
  3. js实现排序去重计算字符次数
  4. Codeforces Round #602 (Div. 2) D2. Optimal Subsequences stl 黑科技
  5. codeforces 940E Cashback 有趣的dp
  6. 控制反转 php,[PHP学习] 控制反转以及依赖注入的日常使用
  7. Linux查看和剔除当前登录用户-转
  8. 2021 年百度之星·程序设计大赛 - 初赛二 1002 随机题意(区间贪心)
  9. web安全day10:通过实验理解windows域的OU和GPO
  10. 微观社会调查数据:中国家庭追踪调查 CFPS
  11. SPI通信协议_02
  12. Git(码云)如何把本地仓库提交到远程仓库
  13. MATLAB APP Designer设计之图片处理
  14. 命令行压缩工具7z.exe使用详解
  15. 不是美术生学3D建模多久能上手?靠自学很难学成功吗?
  16. 运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exis
  17. 如何从JavaScript中的数组替换元素?
  18. Android7.0解决 android.os.FileUriExposedException: file:///storage/emulated/0/
  19. 根据污水处理厂的实际情况选型及校准方案
  20. 嫦娥五号探测器成功着地,任务取得圆满成功

热门文章

  1. 使用nodejs Crawler模块 爬取页面dom数据,图片和视频等详解
  2. Js中apply方法详解说明
  3. Java年月的正则表达式_java如何判断是否为有效的年月日
  4. 软件技术的现状以及未来发展趋势
  5. 浅析M-lag技术(后附华为交换机配置命令)
  6. google商店上架app被重签名问题记录
  7. [JZOJ5539] psy
  8. 多元回归分析--学习笔记
  9. 2016April Python学习笔记(pandasecharts)
  10. 注意!鄂尔多斯交管发布清明假期全市道路交通出行预警