首页 > 系统相关 >内存检测工具——ASan(AddressSanitizer)的介绍和使用

内存检测工具——ASan(AddressSanitizer)的介绍和使用

时间:2024-03-19 22:36:14浏览次数:27  
标签:AddressSanitizer fsanitize fa 内存 asan ASan main 检测工具

ASan介绍

ASan全称AddressSanitizer,是一种内存错误检测工具,目的是帮助开发者检测和调试内存相关的问题,如使用未分配的内存、使用已释放的内存、堆内存溢出等。ASan是由Google开发的,广泛用于C、C++等语言的代码中。

ASan的工作原理是在编译时将额外的代码插入到目标程序中,对内存的读写操作进行检测和记录。当程序运行时,ASan会监测内存访问,一旦发现内存访问错误,比如越界访问、释放后再次访问等,会立即输出错误信息并中断程序执行,同时提供详细的报告帮助开发者定位问题的源头。

通过使用ASan,开发者可以在早期阶段发现和解决潜在的内存错误问题,有效提高程序的稳定性和安全性。ASan在调试阶段是一个非常有用的工具,但由于其会引入一些性能开销,因此在生产环境中通常不建议启用ASan。

ASan使用

要使用ASan,你需要使用支持ASan的编译器,如Clang或GCC,并开启ASan相关的编译选项。

  1. 使用Clang编译器,在终端执行以下命令:
clang -fsanitize=address -g your_program.c -o your_program
  1. 使用GCC编译器,在终端执行以下命令:
gcc -fsanitize=address -g your_program.c -o your_program

在上述命令中,-fsanitize=address是ASan的编译选项,用于开启ASan。-g选项用于生成调试符号,以支持调试和定位错误。当然,我们也可以通过环境变量的方式加入ASan编译选项,然后编译额时候需要加上环境变量,一般是CFLAGS或者CXXFLAGS。更推荐这种方式,因为通过makefile方式编译的时候,这种方式经常见。

export CFLAGS="-fsanitize=address -g $CFLAGS"
gcc $CFLAGS your_program.c -o your_program

编译完成后,运行生成的可执行文件,ASan会在运行时监测程序的内存访问情况,并在发现错误时提供详细的错误信息,包括错误的位置和类型。

下面是一个使用C语言编写的示例程序,可以用来使用ASan进行内存错误检测

#include <stdio.h>
#include <stdlib.h>

void leak_memory() {
    int* p = malloc(sizeof(int) * 10);
    // 没有释放内存,导致内存泄漏
}

int main() {
    int* arr = malloc(sizeof(int) * 5);
    arr[5] = 10; // 内存访问越界错误

    free(arr); // 使用 free 释放内存

    int* p = malloc(sizeof(int));
    free(p); // 使用 free 释放内存

    int* q = NULL;
    *q = 5; // 使用空指针访问内存错误

    leak_memory();

    return 0;
}

编译并运行

gcc $CFLAGS  asan.c -o asan
./asan 

一切顺利的话,会输出下面这种异常。

=================================================================
==296710==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffff7b700b64 at pc 0x000000400810 bp 0xffffd7b963b0 sp 0xffffd7b963a0
WRITE of size 4 at 0xffff7b700b64 thread T0
    #0 0x40080c in main /home/test/asan.c:11
    #1 0xffff7f38df38 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #2 0xffff7f38e004 in __libc_start_main_impl ../csu/libc-start.c:409
    #3 0x4006ac in _start (/home/test/asan+0x4006ac)

0xffff7b700b64 is located 0 bytes to the right of 20-byte region [0xffff7b700b50,0xffff7b700b64)
allocated by thread T0 here:
    #0 0xffff7f5a6080 in malloc (/usr/lib64/libasan.so.6+0xa9080)
    #1 0x4007b0 in main /home/test/asan.c:10
    #2 0xffff7f38df38 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #3 0xffff7f38e004 in __libc_start_main_impl ../csu/libc-start.c:409
    #4 0x4006ac in _start (/home/test/asan+0x4006ac)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/asan.c:11 in main
Shadow bytes around the buggy address:
  0x200fef6e0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x200fef6e0160: fa fa fa fa fa fa fa fa fa fa 00 00[04]fa fa fa
  0x200fef6e0170: 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e0190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e01a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x200fef6e01b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==296710==ABORTING

看堆栈调用信息可以看到

#0 0x40080c in main /home/test/asan.c:11

asan.c文件中的第11行出现了异常,我们看第11行可以知道,只有5个元素,却要访问第6个元素,导致了数组溢出。
如果你修改好了第11行,重新编译运行,会发现还会有其他异常,可以动手自己实验,把这个程序修复好。

需要特别特别注意的是,ASan会增加程序的运行时间和内存开销,因此主要用于调试和测试阶段,特别不建议在生产环境中启用。

ASan其他选项

除了 -fsanitize=address 外,还有其他 AddressSanitizer 相关的编译选项可供选择。以下是一些常用的 AddressSanitizer 编译选项及其作用:

  1. Memory Sanitizer (-fsanitize=memory):用于检测对未初始化内存或使用已释放内存的操作。这个选项可以帮助发现一些难以察觉的内存错误。
  2. UndefinedBehaviorSanitizer (-fsanitize=undefined):用于检测未定义行为,例如整数溢出、空指针解引用等问题。这有助于发现代码中的潜在 bug。
  3. Thread Sanitizer (-fsanitize=thread):用于检测多线程程序中的数据竞争和死锁问题。这个选项可以帮助识别并修复多线程程序中的并发 bug。
  4. Address Sanitizer with Leak Detection (-fsanitize=leak):启用 AddressSanitizer 的同时,也检测内存泄漏问题。这个选项有助于发现代码中的内存泄漏 bug。
  5. Coverage Sanitizer (-fsanitize=coverage):用于生成代码覆盖率报告,检测程序中哪些部分被执行过。这个选项通常用于代码覆盖率测试和分析。
  6. Kernel Address Sanitizer (-fsanitize=kernel-address):针对 Linux 内核模块开发,用于检测内核中的内存错误。

参考资料

以下是一些比较权威的关于AddressSanitizer的资料,大多数都是英文,有兴趣可以看看。

https://clang.llvm.org/docs/AddressSanitizer.html

https://github.com/google/sanitizers/wiki/AddressSanitizer

https://learn.microsoft.com/zh-tw/cpp/sanitizers/asan

更多精彩内容,请关注同名公众:一点sir(alittle-sir)

标签:AddressSanitizer,fsanitize,fa,内存,asan,ASan,main,检测工具
From: https://www.cnblogs.com/kiwiblog/p/18084121

相关文章

  • DependencyCheck开源的软件组件漏洞检测工具
    DependencyCheck是一个开源的软件组件漏洞检测工具,用于帮助开发人员和安全团队发现项目中使用的第三方库中的已知漏洞。它扫描应用程序的依赖关系,包括第三方库、框架和其他组件,然后与漏洞数据库进行比较,以识别是否存在已公开披露的安全漏洞。1.主要特点包括:1.**自动化扫描:**De......
  • Qt MSVC使用内存泄露检测工具 VLD(Visual Leak Detector)
    一、简介VLD=VisualLeakDetector,是一款用于VisualC++的免费的内存泄露检测工具,官网 kinddragon.github.io, GitHub 。先说优点:为每个泄漏的块提供完整的堆栈跟踪,包括源文件和行号信息(如果可用)。检测大多数(如果不是全部)类型的进程内内存泄漏,包括基于COM的泄漏......
  • Web性能检测工具:Audits
    Chrome为我们提供了非常完善的性能检测工具:Performance和Audits,它们能够准确统计页面在加载阶段和运行阶段的一些核心数据,诸如任务执行记录、首屏展示花费的时长等,有了这些数据我们就能很容易定位到Web应用的性能瓶颈。首先Performance非常强大,因为它为我们提供了非常多的......
  • SCA面面观 | 企业该如何选择组件检测工具?
    一般来说,一个软件应用程序可以被分解成若干部分,为软件程序解耦,以减少整个应用程序的复杂性,这些部分就是软件组件。以一种标准化的方式相互作用,使得组件可以像机器的“零部件”一样被换入或换出,因组件具有独立性、可重用行、高内聚、低耦合等优势,可以帮助企业提高开发效率和质量,减少......
  • 无涯教程-Java 正则 - Matcher boolean hasAnchoringBounds()函数
    java.time.Matcher.hasAnchoringBounds()方法查询此匹配器的区域边界定位。booleanhasAnchoringBounds()-声明以下是java.time.Matcher.hasAnchoringBounds()方法的声明。publicbooleanhasAnchoringBounds()booleanhasAnchoringBounds()-返回值如果此匹配器使用锚......
  • “自适应特征强化与转导信息最大化的iDNA-ABT深度学习模型:新一代DNA甲基化检测工具”
    iDNA-ABT:advanceddeeplearningmodelfordetectingDNAmethylationwithadaptivefeaturesandtransductiveinformationmaximization会议地点:腾讯会议关键词:作者:期刊:Bioinformatics年份:2022论文原文:补充材料:报告人博客链接:https://blog.csdn.net/qq_48480183/article/de......
  • 苹果ios在线签名ipa应用检测工具,制作实现参考方案
    Hello同学们,我是咕噜签名分发可爱多。今天跟大家分享在线签名详解苹果IPA文件在线反编译、插件注入和重新签名的工具步骤。学习iOS开发是一个复杂而丰富的过程,而产品的开发与修复是一个需要不断进步的领域。这里我给大家提供一个详细的步骤,讲解如何分析苹果IPA文件,在线反编译应用程......
  • PieCloudDB Database 自研内存管理器 ASanAlloc:为产品质量保驾护航
    内存管理是计算机科学中至关重要的一部分,它涉及到操作系统、硬件和软件应用之间的动态交互。有效的内存管理可以确保系统的稳定性和安全性,提高系统运行效率,帮助我们最大限度地利用有效的内存资源,合理分配和回收内存,预防各类内存错误。在计算机科学的早期,内存管理是由程序员手动完成......
  • 静态源代码安全检测工具
    1.概述​ 随着网络的飞速发展,各种网络应用不断成熟,各种开发技术层出不穷。在享受互联网带来的各种方便之处的同时,安全问题也变得越来越重要。黑客、病毒、木马等不断攻击着各种网站,如何保证安全成为一个非常热门的话题。​ 根据IT研究与顾问咨询公司Gartner统计数据显示,75%的黑......
  • 雷电模拟器过检测工具,逍遥雷电夜神mumu支持,改真机环境,刷入机型,实现独立IP,易语言开源吧
    这个模拟器支持雷电、逍遥、夜神、mumu这几个都支持的,而且还能一键刷入面具默认是德尔塔版本,然后还能一键刷入LSP框架【需重启才生效】,支持模拟arm手机架构可以过一些软件的检测,算是中控类的,还能独立IP,下面是软件的界面和开源代码,仅供代码学习,有点基础的才行,小白可以学习学习结构......