前言

App 64位包在Android 11上crash,崩溃堆栈也很诡异,报了一个native的空指针,代码中一个函数参数为int64_t类型的指针,并且确定不为空!

分析

在仔细调试时,发现函数中传入的指针地址,和使用时的指针地址不一致,从而导致空指针,但是奇怪的是32位的包就没有这个问题!

在查阅了一些资料,发现是由于Android 11中对于64位的进程,arm v9 cpu启用了MTE( Memory Tagging Extension,内存标记拓展)功能。MTE 的工作原理是对堆栈、堆和全局变量上的每次内存分配的第 56 到 59 个地址位加标记,该标记在具有对 ARM Top-byte Ignore (TBI,顶部字节忽略) 的内核支持的设备上的指针顶部字节中设置。。硬件和指令集会自动检查每次访问内存时是否使用了正确的标记。

在指针顶部字节中错误存储信息的 Android 应用一定会在启用了 MTE 的设备上中断。利用加标记的指针,可以在 MTE 设备可用之前更轻松地检测并拒绝对指针顶部字节的错误使用。

详情可以参考:https://source.android.google.cn/devices/tech/debug/tagged-pointers?hl=zh-cn

另外,里边也提到了什么情况下会导致出现这种问题:
如果应用崩溃,并且您收到包含此链接的提示,这可能意味着存在以下某种情况:

  • 应用尝试释放系统堆分配器未分配的指针。
  • 应用中的某个部分修改了指针的顶部字节。不能修改指针的顶部字节,您需要更改代码来修复此问题。

指针的顶部字节被错误使用或修改的示例包括:

  • 指向特定类型的指针将特定于应用的元数据存储在前 16 个地址位中。
  • 指针的类型转换为双精度,然后又恢复为原来的类型,因此丢失了较低的地址位。
  • 代码计算不同堆栈帧的局部变量地址之间的差异,作为测量递归深度的方法。

所以如果出现了这种类似的错误,上面列举的这几种情况要额外注意!

关于TBI

最高字节忽略 (TBI) 是 ARMv8 引入的一项功能,它通过忽略虚拟地址的最高有效 8 位来提供内存标记功能。
尽管 64 位 ARM 寄存器是 64 位宽的,但虚拟地址要求高 16 位必须是 0x0000 或 0xFFFF。 TBI 是一种硬件功能,由 AArch64 引入,它允许软件使用 64 位指针的 8 个最高有效位作为标记。 这是通过在翻译控制寄存器(Translation Control Register)中启用内存标记支持来完成的。 启用后,虚拟地址的前(高)八位 (即63~56位) 将被忽略。

解决

方案一(不推荐)

上边文档中给了一个临时的过渡方案:

<application android:allowNativeHeapPointerTagging="false">...
</application>

方案二

上边的方案虽然不会再报错,但是既然mte已经给你报了内存使用的错误,那么就需要你去检查一下自己的代码,是否出现上述的可能情况。
发现上边传入的int64_t指针,在一个函数内部会转成double,然后获取的时候又转回了int64_t,由于存在精度的丢失,导致前后的地址不一致。这也验证了前边列的一条:指针的类型转换为双精度,然后又恢复为原来的类型,因此丢失了较低的地址位。

参考:
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/enhancing-memory-safety
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/enhanced-security-through-mte

Android 11中对于64位应用arm执行MTE导致crash的问题相关推荐

  1. MongoDB中关于64位整型存储解决方案

    为什么80%的码农都做不了架构师?>>>    社区内一哥们@smcboy 提出关于php中操作MongoDB存储整数问题,找到点资料花点时间翻译过来,是个很好的学习方式.@红薯 那 ...

  2. Oracle instantclient 11.2 (64位)安装与配置tnsnames.ora,并使用PL/SQL Develpoer14(64位)连接数据库

    1.在电脑上安装Oracle instantclient 11.2 (64位),安装之后目录为:D:\app\XX\product\11.2.0\client_2 2.在D:\app\XX\produ ...

  3. 无法在VMware Player中安装64位系统

    无法在VMware Player中安装64位系统 下载了VMware Player用来安装ubuntu的64位系统,配置完成后,开启VM.提示bios中未开启intel VT-X 也就是intel的虚 ...

  4. android安全权限管理,Android 11 中的权限更新

    在 Android 11 中,用户能够针对位置信息.麦克风和摄像头指定更精细的权限.此外,如果以 Android 11 或更高版本为目标平台的应用在一段时间内未使用,系统就会重置这些应用的权限.如果应 ...

  5. 在64位win10中开启64位ie浏览器的方法

    在win10中开启64位ie浏览器 话是这样说,但是实际上,64位win10上(通常为ie11),已经不在有所谓32位ie或64位ie了,这是我阅读大量的windows社区文档得到的结果.如下图所示. ...

  6. Android 11 中访问 Android/data 目录的几种方式

    文章目录 方式1:通过 USB 「传输文件」 方式2:通过 FilesActivity Shortcut (1)ShortcutHelper 主界面 (2)FilesActivity 界面,可以看到 ...

  7. 如何在Android 11 中正确请求位置权限?以及Android 8 - 11位置权限的变化及适配方法!

    由于现在位置信息变为了敏感数据,因此Android限制了它的使用,尤其在APP后台. 在Android 9 之前,位置权限没有按照前后台分离,APP在前台和后台使用相同的资源. 但是,Google开始 ...

  8. 在win10中开启64位ie浏览器的方法(IE11)

    ** 在64位win10中开启64位ie浏览器的方法(IE11) 步骤一 打开ie浏览器,设置->Internet选项->高级,找到,启用增强保护模式 和 针对增强保护模式启用64位进程, ...

  9. 重要变更 | Android 11 中的软件包可见性

    在 Android 10 及之前的版本中,应用可以通过 queryIntentActivities() 这样的方法获取到设备中所有已安装的应用列表.在大多数情况下,这种访问权限远超出了应用实际所需要的 ...

最新文章

  1. 一款功能齐全的网管软件:Ip-tools
  2. Websocket协议的学习、调研和实现
  3. springboot 配置webservice接口
  4. MySQL-ProxySQL中间件Admin Schemas介绍
  5. appboot-7227
  6. 有关圣诞节表白的c语言程序,关于圣诞节表白唯美的句子
  7. Ubuntu默认防火墙UFW命令大全
  8. XtraReport报表控件
  9. 台式计算机怎样能搜无线连接,台式电脑如何连接无线网络
  10. u8系统更改了服务器,用友u8服务器地址修改
  11. 1449异常 mysql_连接MySQL时出现1449与1045异常解决办法
  12. 太爽了!35岁程序员被裁后反而实现财富自由!
  13. 你是从哪个细节发现女朋友出轨的?
  14. ez_pz_hackover_2016
  15. Jvm-Sandbox-Repeater的部署
  16. 软件体系结构期末考试复习题(题中页码 与软件体系结构原理、方法与实践第2版 张友生编著 匹配)
  17. 计算机网络基础知识—— 各层功能及网络层
  18. Java学习之路——数组排序法(冒泡、直选、插入、反转)
  19. 软件著作权登记申请分公司可以作为著作权人申请软件著作权登记证书吗??怎么申请呢?需要提供资料?
  20. 将win10 v2004-20H2-21H1更新到 Win10 21H2

热门文章

  1. java爬取百度贴吧吧内所有帖子数据(图文详解)
  2. 基于web的图书管理系统_基于RFID的图书馆资产管理系统--RFID资产管理--新导智能...
  3. CSS(二)元素基础样式、字体属性、文本属性
  4. [Read]XXJ00172《算法导论》第20章 van Emde Boas 树
  5. Cryp.1.大整数相乘---分治法
  6. 闰年为何是被4和400除,而100除却不行?
  7. vue+echarts实现热力图
  8. 讲讲计算机大牛冯诺依曼一些有趣的故事
  9. 学习 canvas (七)实现圆球水波进度
  10. Windows Server群集感知更新(CAU)-下