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

Android 中 调试和减少内存错误

Android 中 调试和减少内存错误

ASan

概述

官网连接: https://developer.android.com/ndk/guides/asan?hl=zh-cn

  • ASan API 27开始
  • HWASan(替换AScan)
    • 从 NDK r21 和 Android 10(API 级别 29)开始
    • 适用于 64 位 Arm 设备
    • 性能比AScan更好

主要功能

  • 堆栈和堆缓冲区上溢或下溢
  • 释放之后的堆使用情况
  • 超出范围的堆栈使用情况
  • 重复释放或错误释放

示例应用

示例应用展示了如何为 hwasan 配置 build 变体。

模拟出几个内存错误的问题

1. 越界访问 (Buffer Overflow/Underflow)

#### 问题描述: 当程序试图访问数组或缓冲区以外的内存时,就会发生越界访问错误。这类问题往往导致数据损坏,崩溃或安全漏洞。 #### 具体表征:

  • 程序崩溃:可能导致应用无预警地关闭。
  • 数据损坏:错误地重写了其他变量的值。
  • 安全漏洞:可能被利用执行恶意代码。

#### 示例代码:

int array[5] = {0};
int value = array[10]; // 越界读取
array[-1] = 3;        // 越界写入
2. 使用后释放 (Use After Free)

#### 问题描述: 当程序释放了一块内存后仍然尝试使用它时,就会发生使用后释放错误。这是一种非常危险的安全漏洞。 #### 具体表征:

  • 不可预知的行为:可能导致程序执行一段随机的内存操作。
  • 程序崩溃:访问被释放内存可能导致程序无法继续执行。
  • 内存损坏:可能不经意间修改了由其他部分的程序占用的内存。

#### 示例代码:

char *ptr = new char[20];
delete [] ptr; // 释放内存
strcpy(ptr, "这是错误的使用!"); // 在释放后使用内存
3. 内存泄露 (Memory Leak)

#### 问题描述: 未能释放不再使用的内存导致内存泄露。虽然它不会立即导致程序崩溃,但会随着时间推移而逐渐消耗系统资源。 #### 具体表征:

  • 内存消耗增加:随着程序的运行,预期的内存使用量会不断增加。
  • 性能降低:可用内存减少可能导致系统运行变慢,甚至出现延迟。
  • 可能的程序崩溃:如果内存泄露严重,系统最终可能耗尽内存,导致应用或系统崩溃。

#### 示例代码:

void func()
{char *ptr = new char[10]; // 分配内存// 这里应该有一些处理// 忘记释放ptr分配的内存
}

这些内存错误问题都是开发过程中应当注意避免的。常规的调试方法和一些专用工具比如Valgrind、AddressSanitizer(ASan)和上文提到的HWAddressSanitizer(HWASan)能够帮助开发者检测并解决这些内存错误。

HWASan输出日志分析

模拟HWAddressSanitizer的日志输出实际会涉及到针对具体错误调用堆栈和内存映射的信息。由于HWASan的具体日志输出会根据实际运行时的环境和错误情境有所不同,下面我将模拟几个内存错误的HWASan日志输出及关键点说明:

1. 越界访问错误
=================================================================
==12345==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00b100004008 at pc 0x000000552abc
WRITE of size 4 at 0x00b100004008 tags: 1c/15 (ptr/mem) in thread T0#0 0x552abc  (/path/to/binary+0x552abc)#1 0x55678f  (/path/to/binary+0x55678f)#2 0x7f7c85dd9c  (/system/lib/hwaddress-sanitizer.so+0x5dd9c)
0x00b100004008 is located 0 bytes to the right of 8-byte region [0x00b100004000,0x00b100004008)
allocated by thread T0 here:#0 0x7f7c85ca58  (/system/lib/hwaddress-sanitizer.so+0x5ca58)#1 0x5556f4  (/path/to/binary+0x5556f4)#2 0x555979  (/path/to/binary+0x555979)
SUMMARY: HWAddressSanitizer: tag-mismatch /path/to/binary (0x552abc) WRITE 0x00b100004008
=================================================================

#### 关键点说明:

  • tag-mismatch 表示检测到内存标签不匹配,这通常提示内存访问错误。
  • WRITE of size 4 说明试图写入4个字节的数据。
  • address 0x00b100004008 at pc 0x000000552abc 显示了发生错误的内存地址和程序计数器的地址。
  • 调用堆栈(call stack)提供了错误发生时的函数调用序列。
  • 0x00b100004008 is located 0 bytes to the right of 8-byte region 说明写操作是在8字节区域的右侧进行的,这是越界访问。
2使用后释放错误

================================================================= ==12345==ERROR: HWAddressSanitizer: use-after-free on address 0x00b100004010 at pc 0x000000552efc READ of size 8 at 0x00b100004010 tags: 1c/00 (ptr/mem) in thread T0    #0 0x552efc  (/path/to/binary+0x552efc)    #1 0x556abc  (/path/to/binary+0x556abc)    #2 0x7f7c85dd9c  (/system/lib/hwaddress-sanitizer.so+0x5dd9c) 0x00b100004010 is located 0 bytes inside of 10-byte region [0x00b100004010,0x00b10000401a) freed by thread T0 here:    #0 0x7f7c85caff0  (/system/lib/hwaddress-sanitizer.so+0xcaff0)    #1 0x555999  (/path/to/binary+0x555999)    #2 0x5.#2 0x7f7c85dd9c  (/system/lib/hwaddress-sanitizer.so+0x5dd9c)
0x00b100004010 is located 0 bytes inside of 10-byte region [0x00b100004010,0x00b10000401a)
freed by thread T0 here:#0 0x7f7c85caff0  (/system/lib/hwaddress-sanitizer.so+0xcaff0)#1 0x555999  (/path/to/binary+0x555999)#2 0x556df9  (/path/to/binary+0x556df9)
previously allocated by thread T0 here:#0 0x7f7c85ca58  (/system/lib/hwaddress-sanitizer.so+0x5ca58)#1 0x5557e8  (/path/to/binary+0x5557e8)
SUMMARY: HWAddressSanitizer: use-after-free (/path/to/binary+0x552efc) READ 0x00b100004010
=================================================================

#### 关键点说明:

  • use-after-free 表示在释放后再次使用了内存,这是一种严重的错误。
  • READ of size 8 说明尝试读取8个字节的数据。
  • address 0x00b100004010 at pc 0x000000552efc 显示了被错误读取的内存地址和相关的程序计数器的地址。
  • 调用堆栈(call stack)提供了释放内存和随后错误使用该内存的函数调用序列。
  • freed by thread T0 here:previously allocated by thread T0 here: 显示了内存分配及后续释放的位置。

在分析这样的日志时,开发者需要关注堆栈跟踪来确定错误发生的上下文,并修复代码中相应的问题。日志中的内存地址、线程信息以及函数调用序列都是确定问题所在和解决问题的关键信息。在实际的开发工作中,可通过这些详尽的日志来定位问题,优化代码,并进一步强化软件的稳健性和安全性。

Arm 内存标记扩展 (MTE)

  1. 支持ARMv8.5-A及以上架构的处理器
  2. 从 Android 13 开始,部分设备支持 MTE
  3. adb shell grep mte /proc/cpuinfo 出现 Features : [...] mte则表示设备在运行时启用了 MTE

MTE vs ASan

MTE是 ARM 架构提供的硬件特性,它通过在物理内存中添加一些标记信息来辅助检测内存安全错误,它的优势在于提供硬件层面的检测,开销相较软件层面的检测方式较小,特别是在ASYNC模式下。HWASan 是一种基于软件的解决方案,通过修改编译器和运行时环境来检测内存安全问题,特别是地址错误和内存泄漏等。它是谷歌为ARM64架构设计的,针对Android操作系统进行了优化。HWASan在测试和分析阶段特别有用,因为它能提供详尽的错误报告,包括堆栈追踪和内存访问历史等。

如在支持MTE的ARMv8.5及以上架构的设备上,可以优先选用MTE

SYNC 和ASYNC异同

维度SYNC(同步模式)ASYNC(异步模式)
优化目标针对可调试性优化,适用于精确的 bug 检测工具针对 bug 报告的性能优化,偏向于低开销的内存安全检测
处理器反应在接收到违规的加载或存储指令时,会立即终止进程处理器会在到达最近的内核入口(如系统调用或计时器中断)时终止进程
错误报告返回SIGSEGV,提供内存访问和故障地址的详细信息返回SIGSEGV,但是不记录错误地址或内存访问
配合Android分配器分配器会记录每次分配和取消分配的堆栈轨迹以提供更好的错误报告不进行此操作
应用场景用作测试阶段的HWASan的更快替代方案,或生产环境中的应用出现漏洞时的安全缓解措施。对经过严格测试的代码库(已知其内存安全 bug 的密度较低)降低内存安全漏洞的生产环境

两种模式的相同点包括:
在进行硬件辅助的内存安全错误检测时,SYNC和ASYNC都可以监测到内存安全错误。一旦发现标记不匹配,两种模式均会触发处理器的响应,终止进程并返回SIGSEGV。在这两种模式下,都可以在测试阶段运用来找出内存安全bug。

给自己分配的内存打TAG

scudo 实现代码

  • setRandomTag 函数:该函数是用来为给定的指针 Ptr 设置一个随机的内存标签。
  • untagPointer 函数:这个函数会移除指针 Ptr 的内存标签
  • loadTag 函数:此函数似乎用于返回指针 Ptr 上的内存标签
  • addFixedTag 函数:这个函数用于给一个指针 Ptr 添加一个固定的标签 Tag
  • allocatorSupportsMemoryTagging 模板函数:此函数用于确定是否支持内存标记。

使用场景

  1. 内存错误检测:在分配和释放内存时为其打上Tag,可以帮助检测内存安全错误,如缓冲区溢出、使用后释放等。当一个内存区域被释放后,您可以为其分配一个新的Tag,如果之后系统尝试使用相同的旧Tag访问这块内存,MTE机制将检测到错误,并产生一个异常。
  2. 运行时监控和诊断:打标签的内存使得开发者可以追踪内存访问模式,识别内存是如何被程序的不同部分访问的。这在调试过程中尤为有用,因为它可以帮助发现那些隐蔽的内存错误。
  3. 保护关键数据:通过给敏感数据打个特定的Tag,你可以确保只有被授权的代码能够访问这些数据。如果其他不相关的代码尝试访问,标签不匹配会触发异常,这为敏感数据提供了一层额外的保护。
  4. 内存使用分析:Tag可以作为分析工具,以了解某类内存分配的分布和生命周期。例如,通过给特定类型的对象或资源分配统一的Tag,可以在运行时分析其分布情况。
  5. 内存泄露排查:如果一个内存块长时间没有释放,并且带有与之关联的Tag,那么这可能是一个内存泄露的迹象。分析这些留存的Tag可以帮助追踪潜在的内存泄露点。

进阶

Arm 撰写的 Android OS MTE 用户指南

GWP-ASan

GWP-ASan(GWP-ASan Will Provide Allocation SANity) 是一种原生内存分配器功能,可帮助查找释放后使用和堆缓冲区溢出 bug。

  1. GWP-ASan 不需要源代码或重新编译
  2. 适用于以 Android 11(API 级别 30)以上

概述

  1. GWP-ASan启用情况:在进程启动以及zygote派生时,系统会随机选择一些应用和平台可执行文件启用GWP-ASan。
  2. 作用:GWP-ASan旨在帮助开发者发现与内存相关的错误,并帮助应用准备好对ARM内存标记扩展(MTE)的支持。
  3. 内存分配拦截:一旦启用,GWP-ASan会随机拦截堆分配的子集,并将它们移入特殊区域,以发现通常难以检测的堆内存损坏错误。
  4. 低采样率的效果:即使是低采样率,只要用户基数足够大,也能够发现常规测试中未能发现的堆内存安全错误。
  5. 错误检测示例:GWP-ASan已在Chrome中发现大量错误。
  6. 信息收集:GWP-ASan为它拦截的所有分配收集额外信息,这些信息有助于内存安全违规的调试,且会被自动加入到原生代码的崩溃报告中。
  7. 性能影响:启用GWP-ASan后,会产生较小的CPU开销。
  8. 资源消耗:GWP-ASan会带来一定的固定RAM开销,目前累计每个受影响进程大约70KiB。

获取检测到“释放后堆使用”或“堆缓冲区溢出” bug

ActivityManager#getHistoricalProcessExitReasons json格式

[{"processName": "com.example.app","pid": 12345,"reason": "CRASH","timestamp": 1617998745000,"description": "NullPointer exception in MainActivity","trace": "java.lang.NullPointerException: Attempt to invoke virtual method on a null object reference\n\tat com.example.MainActivity.onCreate(MainActivity.java:85)\n\t...","importance": "FOREGROUND_SERVICE","status": "SIGNAL 9"},{"processName": "com.example.serviceapp","pid": 12346,"reason": "USER_REQUESTED","timestamp": 1617998746000,"description": "User requested force stop","trace": "","importance": "VISIBLE","status": "SIGNAL 9"},

相关文章:

Android 中 调试和减少内存错误

Android 中 调试和减少内存错误 ASan 概述 官网连接: https://developer.android.com/ndk/guides/asan?hlzh-cn ASan API 27开始HWASan(替换AScan) 从 NDK r21 和 Android 10(API 级别 29)开始适用于 64 位 Arm 设…...

证券市场概述

证券市场 证券市场参与者证券发行市场(一级市场)证券发行方式(按发行对象)证券发行方式(按有无中介)证券交易市场(二级市场)证券交易所场外交易市场(店头市场、柜台市场&…...

什么是数据结构

一、什么是数据结构 1.数据结构研究计算机数据间的关系 2.包括数据的逻辑结构和储存结构及其操作 数据的逻辑结构:表示数据运算之间的抽象关系 按每个元素可能具有的直接前趋数和后继数将逻辑结构分为“线性结构”和“非线性结构”两大类 数据的储存结构&#…...

基于springboot+vue实现的学校田径运动会管理系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…...

HarmonyOS 应用开发之FA模型绑定Stage模型ServiceExtensionAbility

本文介绍FA模型的三种应用组件如何绑定Stage模型的ServiceExtensionAbility组件。 PageAbility关联访问ServiceExtensionAbility PageAbility关联访问ServiceExtensionAbility和PageAbility关联访问ServiceAbility的方式完全相同。 import featureAbility from ohos.ability…...

Java 中的单例模式

引言: 在 Java 编程中,单例模式是一种常见的设计模式,它保证一个类只能创建一个实例,并提供一个全局访问点。单例模式在很多场景下都非常有用,比如线程池、日志系统、数据库连接池等。本文将详细介绍 Java 中单例模式的…...

鸿蒙OS开发实例:【ArkTS类库多线程I/O密集型任务开发】

使用异步并发可以解决单次I/O任务阻塞的问题,但是如果遇到I/O密集型任务,同样会阻塞线程中其它任务的执行,这时需要使用多线程并发能力来进行解决。 I/O密集型任务的性能重点通常不在于CPU的处理能力,而在于I/O操作的速度和效率。…...

OpenStack部署

目录 一、安装环境 1.无网络使用该命令 2.修改主机名 3.配置hosts解析 4.配置本机免密 5.关闭防火墙和SElinux策略 6.关闭NewworkManager 7.修改yum源 7.1下载阿里源 7.2清空并加载缓存yum源 8.安装基本工具 9.系统升级 10.安装OPenStack的yum仓库 11.修改OPenSt…...

Java中的多线程和线程安全问题

线程 线程是操作系统进行调度的最小单位。一个进程至少包含一个主线程,而一个线程可以启动多个子线程。线程之间共享进程的资源,但也有自己的局部变量。多线程程序和普通程序的区别:每个线程都是一个独立的执行流;多个线程之间是…...

java Web会议信息管理系统 用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 jsp 会议信息管理系统是一套完善的web设计系统,对理解JSP java SERLVET mvc编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发,数据库为Mysql5.0&am…...

lock4j学习记录

一种简单的,支持不同方案的高性能分布式锁 简介 lock4j是一个分布式锁组件,其提供了多种不同的支持以满足不同性能和环境的需求。 立志打造一个简单但富有内涵的分布式锁组件。 特性 简单易用,功能强大,扩展性强。支持redis…...

【C++庖丁解牛】自平衡二叉搜索树--AVL树

🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 前言1 AVL树的概念2. AVL…...

ES5和ES6的深拷贝问题

深拷贝我们知道是引用值的一个问题,因为在拷贝的时候,拷贝的是在内存中同一个引用。所以当其中的一个应用值发生改变的时候,其他的同一个引用值也会发生变化。那么针对于这种情况,我们需要进行深度拷贝,这样就可以做到…...

阿里云发送短信配置

依赖 <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.2.1</version> </dependency> <dependency><groupId>org.apache.httpcomponents</groupId&g…...

axios封装,请求取消和重试,请求头公共参数传递

axios本身功能已经很强大了&#xff0c;封装也无需过度&#xff0c;只要能满足自己项目的需求即可。 常规axios封装&#xff0c;只需要设置&#xff1a; 实现请求拦截实现响应拦截常见错误信息处理请求头设置 import axios from axios;// 创建axios实例 const service axios…...

隐私计算实训营学习五:隐语PSI介绍及开发指南

文章目录 一、SPU 实现的PSI介绍1.1 PSI定义和种类1.1.1 PSI定义和种类1.1.2 隐语PSI功能分层 1.2 SPU 实现的PSI介绍1.2.1 半诚实模型1.2.2 PSI实现位置 二、SPU PSI调度架构三、Secretflow PSI开发指南四、隐语PSI后续计划 一、SPU 实现的PSI介绍 1.1 PSI定义和种类 1.1.1 …...

ES的RestClient相关操作

ES的RestClient相关操作 Elasticsearch使用Java操作。 本文仅介绍CURD索引库和文档&#xff01;&#xff01;&#xff01; Elasticsearch基础&#xff1a;https://blog.csdn.net/weixin_46533577/article/details/137207222 Elasticsearch Clients官网&#xff1a;https://ww…...

linux通用命令 ssh命令连接慢问题排查

系列文章目录 文章目录 系列文章目录一、 ssh 连接慢3.1 查找原因3.2 解决方案 一、 ssh 连接慢 最近的 koji 服务器 使用 ssh 连接很慢。 3.1 查找原因 可以通过 ssh -vvv 192.168.0.123 或 time ssh root192.168.0.123 exit 查找原因如下&#xff1a; SERVER的SSHD会去DN…...

7.卷积神经网络与计算机视觉

计算机视觉是一门研究如何使计算机识别图片的学科&#xff0c;也是深度学习的主要应用领域之一。 在众多深度模型中&#xff0c;卷积神经网络“独领风骚”&#xff0c;已经被称为计算机视觉的主要研究根据之一。 一、卷积神经网络的基本思想 卷积神经网络最初由 Yann LeCun&a…...

Linux|如何管理多个Git身份

摘要 关于如何管理不同项目和多个Git身份。 作为一名通用软件开发者&#xff0c;我经常发现自己在处理各种各样的项目&#xff0c;每个项目都有自己的要求和期望。这包括为个人、工作和客户项目管理不同的Git身份。以下是我组织Git仓库以简化这一过程的方法。 目录组织 我将我的…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...