当前位置: 首页 > news >正文

内存分析工具的使用——AddressSanitizer

一、c/c++中的内存问题

memory corruption,内存崩溃或者说内存损坏。在c/c++程序中,有相当一部分的Bug是由内存引起的,也就是刚刚提到的内存崩溃。说得再通俗一些,往往和内存的非法访问有关。内存问题,轻则导致程序失能,中则导致程序崩溃,重则引起系统瘫痪。
因此,在c/c++编程的过程中,对内存的管理要求非常严格。但灵活多变的指针往往又让很多开发者无法安全的进行内存的处理,即使在新的C++标准中使用了智能指针或者说自行进行了RAII的封装,仍然有可能造成指针引起的内存错误。当然,并不是说c/c++中指针是内存问题的万恶之源,其它情况如数组越界访问等均可以出现类似的问题。
基于上面的内存的问题,很多针对内存进行控制的相关工具也有很多。其中,有静态内存检查工具(Cppcheck等)和动态内存检查工具(valgrind等)。本文介绍一个动态内在检查工具,GAS。

二、GAS

GAS,google address sanitizer,也称为ASan,它是google公司开发的一个快速的内在检测工具。相比于Valgrind对程序的影响,ASan的速度那相当快了。要想监测内存,最好的办法是什么?当然是替换掉编译器的相关内存管理接口了。ASan就提供了一个插桩模块(编译器检测模块LLVM pass)和一个提供malloc等函数替代接口的运行时库。
ASan早期就与LLVM(3.1)进行了结合,将其插桩模块整合到了Clang项目中。后来在Gcc4.8中,也整合了GAS的相关模块,但其配合不太完善,所以推荐使用Gcc4.9以上版本。ASan还有一个专门提供给内核使用的版本KASAN,有兴趣可以搞一下。

三、基本原理

ASan使用的内存检测机制是使用影子内存(shadow memory)来记录当前内存是否可以安全访问的方式。其通过影子内存与常规内存(normal memory)进行映射以期安全的管理内存。通过代码插桩来检查程序运行时影子内存的状态。
当编译器运行时,其通过替代的分配内存管理接口,在内存分配和回收后的区域进行“投毒”(poisoned),形成所谓的有毒区域(如果有visual studio系列的反汇编的经验会很容易理解这段话,其实就是对内存进行二次标记管理并设置相关的安全管理区域),这个其它的动态内存管理如数组安全检测的机理基本类似。关于影子内存映射的机理和相关细节,请查阅谷歌相关论文,此处不再赘述。

四、ASan支持的内存检查

ASan对常见的内存问题都进行了支持,主要包括下面几点:
1、Use after free
这个比较好理解,它主要是指堆(Heap)内存在释放后又被重新使用。这是一种非常常见的内存问题,类似于下面的代码:

A *a = new A();
delete a;
a->pid = 0;

2、Heap buffer overflow
这也是一种比较常见的内存错误,即堆内存溢出,也就是越界:

char * p = new char[10];
p[11] = 2;

3、Stack buffer overflow
说过了堆溢出怎么能不提栈溢出呢,这个就不举例子了,太简单多见了。
4、Global buffer overflow
全局缓冲区溢出,这都和堆溢出类似。
5、Use after return
返回值使用无效内存,典型的就是返回一个临时变量的指针或引用,看下面的代码:

int * getData(){int tmp[10];return tmp;
}
int * d = getData();

6、Use after scope
使用作用域外的内存空间,和上面的有些类似。看下面的代码:

for(int i = 0;i< 10;i++){}
int p = i;

7、Initialization order bugs
初始化顺序不同引用的问题,这个比较符合C++的特性。这个在前面的分析过好多次,最典型的就是库中的全局变量与调用者之间调用之间的顺序问题,静态变量也有这种可能的现象。
8、Memory leaks
内存泄露,这可是写c/c++程序员的“亲亲”。不管多么高深的开发者,几乎都会遇到这个问题。但有一句话需要说明:内存泄露不可怕,可怕是内存泄露的累积。

五、应用

在基本了解了ASan后,下面举一个例子来进行实践一把。使用ASan的主要步骤分为:

1、编写测试程序

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int heapOver() {char *pBuf = (char *)malloc(10 * sizeof(char));memcpy(pBuf + 10, "abcd1234", 8);free(pBuf);return 0;
}
int *getData() {int *arr = new int[10];delete arr;return arr;
}
int main() {heapOver();int arr[10] = {0};int d = arr[11];int *p = getData();delete p;return 0;
}

2、在编译时增加相关参数
gcc中增加-fsanitize=address选项;如果想获得较好性能,建议增加-O1或更高编译优化选项;增加fno-omit-frame-pointer选项可以提供更友好的堆栈回溯信息

3、编译并运行:

#编译:注意如果不加-g选项,则无法准确的显示出问题的源码位置,可自行测试一下不带-g
~/project/ASanTest$ g++  -fsanitize=address -fno-omit-frame-pointer -g -o asanTest main.cpp
#运行
~/project/ASanTest$ ./asanTest 
=================================================================
==94673==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000001a at pc 0x7f6acbe3a2c3 bp 0x7ffde51ff060 sp 0x7ffde51fe808
WRITE of size 8 at 0x60200000001a thread T0#0 0x7f6acbe3a2c2 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827#1 0x55b7993f9381 in heapOver() /home/qt65_project/ASanTest/main.cpp:8#2 0x55b7993f9477 in main /home/fqt65_project/ASanTest/main.cpp:19#3 0x7f6acb629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#4 0x7f6acb629e3f in __libc_start_main_impl ../csu/libc-start.c:392#5 0x55b7993f9284 in _start (/home//qt65_project/ASanTest/asanTest+0x1284)0x60200000001a is located 0 bytes to the right of 10-byte region [0x602000000010,0x60200000001a)
allocated by thread T0 here:#0 0x7f6acbeb4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145#1 0x55b7993f935e in heapOver() /home/qt65_project/ASanTest/main.cpp:7#2 0x55b7993f9477 in main /home/fqt65_project/ASanTest/main.cpp:19#3 0x7f6acb629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00[02]fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8050: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==94673==ABORTING

大家可以依次的进行测试,就会将三种类型的问题,都在运行时暴露出来。分别报得错误是“堆溢出、栈溢出和分配释放不匹配”。而且描述的非常详细和准确,大家可以自己动手实践一把。

六、总结

工欲善其事,必先利其器。不是常说,某某是编程界的瑞士军刀么。其实,只要是刀,用好了都会起到事半功倍的效果。要想写出好的代码,除了有思想上的指导,在实践中熟练的应用各种开发工具也是必不可少的。

相关文章:

内存分析工具的使用——AddressSanitizer

一、c/c中的内存问题 memory corruption&#xff0c;内存崩溃或者说内存损坏。在c/c程序中&#xff0c;有相当一部分的Bug是由内存引起的&#xff0c;也就是刚刚提到的内存崩溃。说得再通俗一些&#xff0c;往往和内存的非法访问有关。内存问题&#xff0c;轻则导致程序失能&a…...

linux使用nmcli 管理wifi的命令

在 Linux 系统中&#xff0c;nmcli 是 NetworkManager 的命令行工具&#xff0c;常用于管理网络连接&#xff0c;包括 WiFi。下面是一些常见的使用 nmcli 管理 WiFi 的命令。 1. 显示所有可用的 WiFi 网络 nmcli dev wifi list这个命令会列出当前可以扫描到的 WiFi 网络及其信…...

deepin20.9安装部署 |deepin20.9镜像下载 |基本命令 |手动分区 |开启远程ssh服务

下载deepin20.9 .iso 阿里云 https://mirrors.aliyun.com/deepin-cd/20.9/deepin-desktop-community-20.9-amd64.iso 注意安装过程略 小白参考 &#xff1a; Centos 7.9 安装 图解版 小白必看 最新_centos7.9-CSDN博客文章浏览阅读2.4k次&#xff0c;点赞34次&#xff0c…...

使用PL/SQL Deverloper过程遇见的问题

目录 背景: ORA-01031权限问题&#xff1a; PL/SQL Deverloper显示Oravle中存在的所有表&#xff1a; PL/SQL Deverloper优点: 背景: PL/SQL Developer是由Allround Automations公司开发的一款集成开发环境(IDE),它专门面向Oracle数据库存储的程序单元的开发。随着越来越多…...

pikachu靶场总结(三)

五、RCE 1.RCE(remote command/code execute)概述 RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入操作系统命令或者代码&#xff0c;从而控制后台系统。 远程系统命令执行 一般出现这种漏洞&#xff0c;是因为应用系统从设计上需要给用户提供指定的远程命令操作的…...

onvif相关的http api有哪些功能点

ONVIF 提供了一系列 HTTP API&#xff0c;用于访问和控制支持 ONVIF 的设备。这些 API 基于 SOAP 协议&#xff0c;通过 HTTP 协议传输。主要的 API 分为几个关键的服务类别&#xff0c;每个类别都有特定的操作。以下是 ONVIF 相关的 HTTP API 概述&#xff1a; 1. 设备管理服…...

AI大模型是如何改变我们的日常生活的?

随着AI大模型的不断发展和优化&#xff0c;它已经在各个领域展现出了巨大的潜力和广泛的应用。无论是在科技创新、医疗健康、金融服务、教育培训还是日常生活中&#xff0c;AI大模型都有着重要的作用。它不仅可以帮助人们提高工作效率、提供个性化的服务&#xff0c;还能够改善…...

kubernetes部署Nexus(Helm3)

参考文献&#xff1a; https://help.sonatype.com/en/single-data-center-on-premises-deployment-example-using-kubernetes.htmlhttps://github.com/sonatype/helm3-chartshttps://support.sonatype.com/hc/en-us/articles/7706583820691-How-to-install-Nexus-Pro-instance…...

PDF无法导出中文

font/SIMSUN.TTC with Identity-H is not recognized. 查看BaseFont源码发现".ttc," 改为"SIMSUN.TTC,a"提示数字转换异常 改为"SIMSUN.TTC,11"提示数字索引必须介于0和1之间 改为0或1结果正常 BaseFont baseFont BaseFont.createFont("/U…...

【docker】mysql8.0 的 docker 安装

安装 指定mysql 的安装版本8.0.18 拉取镜像 docker pull mysql:8.0。18创建目录 mkdir -p /opt/docker_volumn/mysql/conf mkdir -p /opt/docker_volumn/mysql/log mkdir -p /opt/docker_volumn/mysql/data mkdir -p /opt/docker_volumn/mysql/mysql-files此步骤是为了将容…...

vue3中父组件与子组件关系的理解 ------类比java中的启动类,类,对象等概念来解释一下

编程时的一点感受&#xff1a; 感觉子组件本身像是java的一个类&#xff0c;父组件像是启动类&#xff0c;父组件里引用子组件像是创建子组件的对象 查找资料后&#xff0c;发现确实如此&#xff0c;在很多方面&#xff0c;Vue 组件确实可以与面向对象编程中的类进行类比。…...

Java设计模式——装饰模式

目录 模式动机 模式定义 模式结构 类图 代码分析 示例&#xff1a;动态添加功能的流 组件接口 具体组件 装饰抽象类 具体装饰类 客户端 模式分析 核心思想 动态扩展功能 组合优于继承 优点 动态扩展功能 组合优于继承 代码复用性高 符合开闭原则 缺点 增加…...

【TouchSocket 和 client.GetStream 区别】

TouchSocket 和 client.GetStream() 是用于网络通信的不同工具和方法&#xff0c;但它们的功能层面和适用范围也有明显区别。下面我来详细解释 TouchSocket 和 client.GetStream() 的差异。 1. TouchSocket TouchSocket 是一个完整的 网络通信框架&#xff0c;专注于为开发者…...

怎么利用商品详情API接口实现数据获取与应用?

在当今数字化的商业时代&#xff0c;高效获取和利用商品数据对于企业和开发者来说至关重要。商品详情 API 接口为我们提供了一种便捷的方式来获取丰富的商品信息&#xff0c;从而实现各种有价值的应用。本文将深入探讨如何利用商品详情 API 接口实现数据获取与应用。 一、商品…...

【AGC005D】~K Perm Counting(计数抽象成图)

容斥原理。 求出f(m) &#xff0c;f(m)指代至少有m个位置不合法的方案数。 怎么求&#xff1f; 注意到位置为id&#xff0c;权值为v ,不合法的情况&#xff0c;当且仅当 v idk或 v id-k 因此&#xff0c;我们把每一个位置和权值抽象成点 &#xff0c;不合法的情况之间连一…...

【React】setState (useState) 是怎么记住上一个状态值的?

在 React 中&#xff0c;setState 通过 React 内部的状态管理机制来记住上一个状态值。即使每次组件重新渲染时&#xff0c;函数组件会被重新执行&#xff0c;React 仍能通过其内部的状态管理系统保持和追踪组件的状态变化。下面详细解释其工作原理&#xff1a; 1. setState 的…...

Vue3 使用CryptoJS加密

为什么要加密&#xff1f; 现在的互联网世界充满了各种各样的信息&#xff0c;有些信息非常重要&#xff0c;比如密码、个人信息等。如果我们把这些信息直接发送到服务器&#xff0c;别人可能会截取到&#xff0c;然后偷走我们的信息。为了避免这种情况发生&#xff0c;我们需…...

Feign的使用

一、Feign 介绍 Feign 是一个声明式的 HTTP 客户端&#xff0c;它使得编写 HTTP 客户端变得更加简单。在微服务架构中&#xff0c;使用 Feign 可以轻松地调用其他服务。Feign 内置了 Ribbon 实现负载均衡。 二、Feign 的使用步骤 引入依赖&#xff1a; 在项目的 pom.xml 文件…...

前端反接保护:实用方案解析与探讨

前端反接保护通常采用肖特基二极管方案或PMOS/NMOS方案&#xff0c;本文另外介绍一种理想二极管方案。 1、肖特基二极管方案 由于肖特基二极管具有正向导通电压&#xff0c;只能用于小电流场合&#xff0c;甚至于直接使用普通的整流二极管。比如1A电流&#xff0c;设D1的正向…...

【C++】第五节:内存管理

1、C/C内存分布 看下面一段代码 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(s…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...