首页 > 系统相关 >关于asan内存检测工具的原理和使用

关于asan内存检测工具的原理和使用

时间:2023-01-04 16:55:48浏览次数:63  
标签:return void free char 内存 asan 检测工具

  Hello,各位看官好,小弟的公司最近开始使用asan这个工具了,最近在晚上查了一下,不查不知道,一查吓一跳,这个工具真的是神一般的工具,所以我就花了一点时间整理了一下asan工具的用法。

    一、asan是什么?

      ASAN(全称为AddressSanitizer),是一种比valgrind更为强大的检测工具,通过这个工具,我们可以轻松检测出内存的问题并且可以初步将问题进行分类,比如堆溢出,栈溢出等等。

    二、和其他检测工具相比较

      最有名的检测工具就是valgrind工具,但是这个工具有一个大问题就是运行时候占用的内存过大,从而导致程序运行过慢,而asan完美的解决了这个问题,它大概只会在原有程序基础上拖慢1倍,而valgrind则会拖慢30~50倍。

    三、asan工具的使用前提

      1、asan的使用前提必须要在gcc或者g++4.8以上的编译器中,当然这个因为楼主所使用的编译器默认为5.4,因此不存在这种问题。

      2、asan中一定要有libasan.so.3这个库,如果没有是不行的。

      3、编译选项中需要添加两个编译选项,其一是(-fsanitize=address)这个选项添加的原因是将asan添加进入编译中,其二是添加-g,这个就是增加堆栈信息,只有这样才能看出函数名称。

      4、在asan工具中,我们还可以设置一些编译选项,比如

        ASAN_OPTIONS是Address-Sanitizier的运行选项环境变量。

        # halt_on_error=0:检测内存错误后继续运行

        # detect_leaks=1:使能内存泄露检测

        # malloc_context_size=15:内存错误发生时,显示的调用栈层数为15

        # log_path=/home/xos/asan.log:内存检查问题日志存放文件路径

        # suppressions=$SUPP_FILE:屏蔽打印某些内存错误

        除了上述常用选项,以下还有一些选项可根据实际需要添加:

          # detect_stack_use_after_return=1:检查访问指向已被释放的栈空间

          # handle_segv=1:处理段错误;也可以添加handle_sigill=1处理SIGILL信号

          # quarantine_size=4194304:内存cache可缓存free内存大小4M

    四、asan能够检测出的内存问题

      1、use after free(free之后继续使用)

      2、Heap after  overflow(堆溢出)

      3、stack  after  overflow(栈溢出)

      4、global after  overflow(全局变量溢出)

      5、use  after  return(返回之后继续使用)

      6、use after  scope(超过作用域)

      7、 Initialization order bugs(初始化顺序bug)

      8、Memory leaks(内存泄漏)

    五、asan使用原理

      1、看了一些asan的使用原理,其实也还比较简单,他的核心算法有两点,其一就是就是在他的周边添加监控内存,其二就是映射,这样在使用的时候只要检测到是否踏入周边内存就可以知道是否报错

    六、代码解析

      

// 测试全局溢出 void testBuffer() {     globalBuffer[100] = 10;     return; }
void heapOverFlow() {     char *heap_buf = (char *)malloc(sizeof(char) * 32);     memcpy(heap_buf + 30, "overflow", 8);     free(heap_buf);     return; }
void vectorheapOverFlow() {     vector<int> test;     test.push_back(0);     test.push_back(0);     test[10] = 0;     return; }
void stackOverFlow() {     char test[4];     test[4] = 0; }
void wildPointerOverFlow() {     char *p = (char *)malloc(30);     free(p);     if (p == NULL)     {         std::cout<<"p is NULL"<<std::endl;     }     else if (p == nullptr)     {         std::cout<<"p is nullptr"<<std::endl;     }     else     {         std::cout<<"p is true"<<std::endl;     }
    int a = p[1];     return; }
void wildPointerAnotherFlow() {     int *p = new int;     delete p;     std::cout<<"p is 11111:"<<p<<std::endl;     long *p1 = new long;     std::cout<<"p1 is 22222:"<<p1<<std::endl;     *p1 = 100;     std::cout<<"p1 is 33333:"<<*p1<<std::endl;     *p = 23;     std::cout<<"p1 is 44444:"<<*p1<<std::endl;     std::cout<<"p is 555555:"<<*p<<std::endl;     return; }
void doubleFree() {     char *p = (char *)malloc(10);     free(p);     free(p);     return; }

void exitScope() {     int *p;     {         int num = 10;         p =&num;     }
    std::cout<<"p is:"<<*p<<std::endl; }
char * memoryleak() {     char *str = (char *)malloc(32);     strcpy(str,"overflow");     return str; }
int main(int argc, char *argv[]) {     // 测试全局buffer     // testBuffer();     // 测试堆缓冲区溢出     // heapOverFlow();     // vectorheapOverFlow();     // 测试栈缓冲区溢出     // stackOverFlow();     // 测试野指针     // wildPointerOverFlow();     // wildPointerAnotherFlow();     // double-free     // doubleFree();     // 退出作用閾     // exitScope();     // 内存泄漏     char *str = memoryleak();     // free(str);     return 0; }   以上都是一些作用案例,这些可以给大家参考   七、参考资料   https://github.com/google/sanitizers/wiki/AddressSanitizer PS:补充一下,由于这个博客园没有上传附件的功能,所以libasan.so.1就不能上传了,请大家自行下载。

 

标签:return,void,free,char,内存,asan,检测工具
From: https://www.cnblogs.com/songyuchen/p/17025213.html

相关文章

  • 如何获取 Android 设备的CPU核数、时钟频率以及内存大小
    因项目需要,分析了一下Facebook的开源项目-​​DeviceYearClass​​。DeviceYearClass的主要功能是根据CPU核数、时钟频率以及内存大小对设备进行分级。代码很......
  • java 方法的内存理解
    目录方法调用的基本内存原理方法传递基本数据类型的内存原理基本数据类型(四类八种):数据值存储在自己的空间中引用数据类型:存储地址值,真实值在地址指向的空间两种数据类型的......
  • Linux内存管理与监控
    内存的监控$freetotalusedfreesharedbufferscachedMem:164024321636049241940046540412714880-/+buffers/cache:......
  • thinkbook14+ R76800h 共用内存2g,导致内存小的问题
    很简单,但是问了好几遍客户也没有给到关键的有用的信息,就是在bois中可用选择集成显卡的内存大小,把2g更换成512就够了(看个人需求,我用来编码,不打游戏,需要更多的内......
  • JavaScript 中的数据是如何存储在内存中的
    JavaScript是什么类型的语言JavaScript是一种弱类型的、动态的语言。那这些特点意味着什么呢?弱类型:支持隐式类型转换的语言称为弱类型语言,不支持隐式类型转换的语言称......
  • java内存管理
    1.java是如何管理内存的 Java的内存管理就是对象的分配和释放问题。(两部分) 分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型......
  • MyEclispe修改最大内存和最小内存的方法
    ......
  • C++/python共享内存交换图片/文本信息
    共享内存保存读取图片OpenShare.cpp#include"OpenShare.h"//共享内存1,,C++发--python传递位姿与图像存储路径intkey_id=1111;intshmid;void*pBuffer;//共......
  • 通用内存分配库tcmalloc的实现
    tcmallocTCMalloc是Google开发的内存分配器,在不少项目中都有使用,例如在Golang中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征:对抗内存碎片、......
  • java 数组的内存分配
    每一个软件都占用一定的内存空间。栈与堆java内存分配int变量例子int等类型的变量无new关键字,不在堆中开辟空间,值直接在栈中赋给变量名。数组的内存数组的初始......