news 2026/4/23 16:11:05

Android应用程序 c/c++ 崩溃排查流程二——AddressSanitizer工具使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android应用程序 c/c++ 崩溃排查流程二——AddressSanitizer工具使用

目录

1.背景

2.ASan工具集成到应用中进行使用

3.使用ASan工具查看日志


1.背景

由于在Android应用中进行c/c++编程会有各种crash或者内存指针异常,如果内存需要查看哪地方进行释放内存是无法通过addr2line或者ndk-stack工具排查出来的,这时就需要使用AddressSanitizer对内存异常的进行深度分析,例如list收尾相连成为环形了,如下:

主要代码逻辑如下:

根本原因:Scudo(Android 11+ 的默认内存分配器)检测到要释放的内存块的头部信息(chunk header)已被破坏 。

直接触发点:在osa_free中释放某个内存块(地址0xd0061100)时,Scudo 验证发现其头部校验和不匹配 。头部可能因内存越界写入(如缓冲区溢出)或使用已释放内存(use-after-free)而损坏 。

重要背景:在崩溃前,您的队列验证代码多次检测到并修复了循环链表("Circular list confirmed! Cycle detected after X steps")。队列结构持续被破坏,暗示存在持续的内存越界写入严重的并发访问问题​ 。

Scudo 本身是一种缓解机制,而 ASan 能更精确地定位内存错误,此处就需要用到ASan工具

2.ASan工具集成到应用中进行使用

1.在AndroidManifest.xml中添加:

android:extractNativeLibs="true"

如下:

2.在gradle中添加

useLegacyPackaging = true

如下是我的配置

如果不行直接把我的配置拷贝进去

packagingOptions { jniLibs { useLegacyPackaging = true // 兼容旧版本Gradle } resources { // 包含所有.so文件 pickFirsts += "**/*.so" // 包含静态库(如果需要) pickFirsts += "**/*.a" } }

3、将wrap.sh 文件添加到src/main/resources/lib目录中的对应目录。我这边是32位的,如下:

wrap.sh内容如下,直接拷贝即可:

#!/system/bin/sh HERE="$(cd "$(dirname "$0")" && pwd)" export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1 ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so) if [ -f "$HERE/libc++_shared.so" ]; then # Workaround for https://github.com/android-ndk/ndk/issues/988. export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so" else export LD_PRELOAD="$ASAN_LIB" fi "$@"

也可以参考:https://developer.android.com/ndk/guides/asan?hl=zh-cn#ndk-build

4.找到asan的动态库,和其他动态库一样集成到项目中

首先我这边是用的32位库,路径如下:

Sdk\ndk\23.1.7779620\toolchains\llvm\prebuilt\windows-x86_64\lib64\clang\12.0.8\lib\linux

然后集成到项目中,这里的流程就是和一般的so包一样进行集成即可

上述的流程就完成了ASan工具的集成

3.使用ASan工具查看日志

上述集成完成,然后我们运行应用,如果有wrap.sh相关的AddressSanitizer打印说明我们集成成功了,如下:

从ASan报告中有几个关键信息点:

  1. 错误类型AddressSanitizer: attempting free on address which was not malloc()-edSUMMARY: AddressSanitizer: bad-free。这直接指明了是无效的释放操作。

  2. 地址位置Address 0xc99ce0f8 is located in stack of thread T20 (Thread-4)。这是最关键的线索,它表明您的程序试图释放(free)的内存地址是一个位于线程栈(stack)上的局部变量,而栈内存是由系统自动管理(函数返回时自动回收)的,绝不能手动释放。

  3. 调用栈:调用栈显示了从liblpa.so开始的函数调用链,错误就发生在这个库中。您需要沿着这个调用栈来定位问题代码。

然后我们使用addr2line工具进一步定位,不会用addr2line工具的可以看前一篇文章:

https://blog.csdn.net/gongjdde/article/details/155744018?sharetype=blogdetail&sharerId=155744018&sharerefer=PC&sharesource=gongjdde&spm=1011.2480.3001.8118

此时我们就定位到错误的位置了,如下:

可以看出来这个是局部的变量,不能被回收,所以导致出现无效的释放,将这行代码删除即可

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:35:37

企业选型智能体的五大核心维度:以商联达为例的实战指南

在数字化转型浪潮中,AI智能体已成为企业提升竞争力的"秘密武器"。面对市场上琳琅满目的解决方案,企业如何避免"踩坑"?本文以商联达为例,拆解AI选型的五大核心维度,助您找到最适合的智能伙伴。一、…

作者头像 李华
网站建设 2026/4/23 11:33:22

数字政府建设的坚实支撑

在数字政府建设浪潮中,政务云凭借安全可控、高效协同的特性,成为提升治理能力的关键抓手。天翼云翼政通iStack一体机通过“一云多芯”架构,适配多种国产化芯片,实现了从IaaS到SaaS的全栈自研,成功入选信通院高质量数字…

作者头像 李华
网站建设 2026/4/23 12:54:42

【私域商城系统是企业构建自主可控电商生态的核心工具】

私域商城系统是企业构建自主可控电商生态的核心工具,旨在通过自有渠道深度运营用户资产,实现低成本获客、高复购转化及品牌价值沉淀。以下是其关键特性及实施要点: 一、核心功能模块 • 全渠道触达与整合 支持小程序、APP、H5、PC端等多终端入…

作者头像 李华
网站建设 2026/4/23 12:12:10

什么是流策略

文章目录为什么需要流策略如何实现流策略流策略的典型应用流策略是一种网络流量管理机制,能够将具有相同特征的报文划分为一类,并为这一类报文提供相同的服务。通过配置流策略,用户可以定义报文分类规则匹配需要单独处理的流量,然…

作者头像 李华
网站建设 2026/4/23 13:36:00

如何将Grok的能力用于MCP服务器

概述 基于我的需求,假设“Trae CN”指的是 Tria Technologies 的 Vision AI-KIT 6490(或类似使用 Qualcomm QCS6490 处理器的边缘 AI 开发套件),这是一个支持高性能 AI 计算的 IoT 硬件平台。MCP(Model Context Protocol)是一个开放协议,用于将 AI 模型连接到外部工具和…

作者头像 李华
网站建设 2026/4/23 16:03:12

数据价值可视化:让数据说话的艺术与科学

数据价值可视化:让数据说话的艺术与科学 引言:数据可视化的“痛点”与“价值缺口” 上周和一位电商运营朋友聊天,她倒了一肚子苦水: “我们每周都做数据可视化——折线图、柱状图、Dashboard 堆了一堆,但老板总说‘看不…

作者头像 李华