内存分析工具的使用——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,内存崩溃或者说内存损坏。在c/c程序中,有相当一部分的Bug是由内存引起的,也就是刚刚提到的内存崩溃。说得再通俗一些,往往和内存的非法访问有关。内存问题,轻则导致程序失能&a…...
linux使用nmcli 管理wifi的命令
在 Linux 系统中,nmcli 是 NetworkManager 的命令行工具,常用于管理网络连接,包括 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 注意安装过程略 小白参考 : Centos 7.9 安装 图解版 小白必看 最新_centos7.9-CSDN博客文章浏览阅读2.4k次,点赞34次,…...

使用PL/SQL Deverloper过程遇见的问题
目录 背景: ORA-01031权限问题: PL/SQL Deverloper显示Oravle中存在的所有表: PL/SQL Deverloper优点: 背景: PL/SQL Developer是由Allround Automations公司开发的一款集成开发环境(IDE),它专门面向Oracle数据库存储的程序单元的开发。随着越来越多…...
pikachu靶场总结(三)
五、RCE 1.RCE(remote command/code execute)概述 RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。 远程系统命令执行 一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的…...
onvif相关的http api有哪些功能点
ONVIF 提供了一系列 HTTP API,用于访问和控制支持 ONVIF 的设备。这些 API 基于 SOAP 协议,通过 HTTP 协议传输。主要的 API 分为几个关键的服务类别,每个类别都有特定的操作。以下是 ONVIF 相关的 HTTP API 概述: 1. 设备管理服…...
AI大模型是如何改变我们的日常生活的?
随着AI大模型的不断发展和优化,它已经在各个领域展现出了巨大的潜力和广泛的应用。无论是在科技创新、医疗健康、金融服务、教育培训还是日常生活中,AI大模型都有着重要的作用。它不仅可以帮助人们提高工作效率、提供个性化的服务,还能够改善…...
kubernetes部署Nexus(Helm3)
参考文献: 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中的启动类,类,对象等概念来解释一下
编程时的一点感受: 感觉子组件本身像是java的一个类,父组件像是启动类,父组件里引用子组件像是创建子组件的对象 查找资料后,发现确实如此,在很多方面,Vue 组件确实可以与面向对象编程中的类进行类比。…...
Java设计模式——装饰模式
目录 模式动机 模式定义 模式结构 类图 代码分析 示例:动态添加功能的流 组件接口 具体组件 装饰抽象类 具体装饰类 客户端 模式分析 核心思想 动态扩展功能 组合优于继承 优点 动态扩展功能 组合优于继承 代码复用性高 符合开闭原则 缺点 增加…...
【TouchSocket 和 client.GetStream 区别】
TouchSocket 和 client.GetStream() 是用于网络通信的不同工具和方法,但它们的功能层面和适用范围也有明显区别。下面我来详细解释 TouchSocket 和 client.GetStream() 的差异。 1. TouchSocket TouchSocket 是一个完整的 网络通信框架,专注于为开发者…...

怎么利用商品详情API接口实现数据获取与应用?
在当今数字化的商业时代,高效获取和利用商品数据对于企业和开发者来说至关重要。商品详情 API 接口为我们提供了一种便捷的方式来获取丰富的商品信息,从而实现各种有价值的应用。本文将深入探讨如何利用商品详情 API 接口实现数据获取与应用。 一、商品…...
【AGC005D】~K Perm Counting(计数抽象成图)
容斥原理。 求出f(m) ,f(m)指代至少有m个位置不合法的方案数。 怎么求? 注意到位置为id,权值为v ,不合法的情况,当且仅当 v idk或 v id-k 因此,我们把每一个位置和权值抽象成点 ,不合法的情况之间连一…...
【React】setState (useState) 是怎么记住上一个状态值的?
在 React 中,setState 通过 React 内部的状态管理机制来记住上一个状态值。即使每次组件重新渲染时,函数组件会被重新执行,React 仍能通过其内部的状态管理系统保持和追踪组件的状态变化。下面详细解释其工作原理: 1. setState 的…...
Vue3 使用CryptoJS加密
为什么要加密? 现在的互联网世界充满了各种各样的信息,有些信息非常重要,比如密码、个人信息等。如果我们把这些信息直接发送到服务器,别人可能会截取到,然后偷走我们的信息。为了避免这种情况发生,我们需…...
Feign的使用
一、Feign 介绍 Feign 是一个声明式的 HTTP 客户端,它使得编写 HTTP 客户端变得更加简单。在微服务架构中,使用 Feign 可以轻松地调用其他服务。Feign 内置了 Ribbon 实现负载均衡。 二、Feign 的使用步骤 引入依赖: 在项目的 pom.xml 文件…...

前端反接保护:实用方案解析与探讨
前端反接保护通常采用肖特基二极管方案或PMOS/NMOS方案,本文另外介绍一种理想二极管方案。 1、肖特基二极管方案 由于肖特基二极管具有正向导通电压,只能用于小电流场合,甚至于直接使用普通的整流二极管。比如1A电流,设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…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...

Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...