内存分析工具的使用——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…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
