本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:踩内存问题一键定位:HWASAN + BinXO无源码内存检测实战指南-华为开发者话题 | 华为开发者联盟
适用版本:DevEco Studio 6.1.0.830 及以上版本
【背景与收益】
什么是 HWASAN?
HWASAN(Hardware-Assisted Address Sanitizer,硬件辅助地址消毒器)是 Clang 开源社区推出的一种内存检测工具,主要用于开发态的内存问题检测。它利用 ARMv8.5 及以上芯片的 MTE(Memory Tagging Extension)硬件特性,在内存访问时通过 tag 比对快速发现踩内存问题。
注意:HWASAN 定位为开发态检测工具,不建议在发布版本中使能。其主要用于开发阶段和测试阶段快速发现内存问题,提升应用稳定性。
在鸿蒙应用开发中,踩内存(Memory Corruption) 是 C++ Native 层最常见的稳定性问题之一。踩内存问题包括堆缓冲区溢出(heap-buffer-overflow)、堆内存释放后使用(heap-use-after-free)、双重释放(double-free)等,这些问题往往导致应用随机崩溃,且由于崩溃现场与根因脱节,定位极其困难。
为什么需要 HWASAN + BinXO?
传统 HWASAN(Hardware-Assisted Address Sanitizer)需要开发者基于源码重新编译,面临以下痛点:
HWASAN + BinXO 方案的核心收益:
• ✅ 无源码插桩:基于 BinXO 二进制编译优化技术,对已编译的 .so 动态库直接进行 HWASAN 插桩,无需源码
• ✅ 一键使能:DevEco Studio 6.1.0.830+ 版本支持 IDE 界面勾选,无需手动添加编译参数
• ✅ 全面覆盖:同时开启源码编译插桩 + 无源码二进制插桩,检测覆盖率大幅提升
• ✅ 快速定位:IDE 集成堆栈跟踪分析工具,直接定位报错栈和申请栈
【技术原理】
BinXO 二进制插桩原理
BinXO 是华为自研的轻量化二进制编译优化器,可以在二进制层级进行优化和运行时信息采集。基于 BinXO 的 SourceLess HWASAN 方案,在汇编层级对已编译的 .so 动态库进行 HWASAN 插桩,实现无源码场景下的内存访问检测。
核心流程如下:
访存指令插桩:在汇编层级识别所有 load/store 访存指令,插入 tag 检查逻辑
保存部分寄存器于栈上,用于后续计算
提取访问地址 addr
计算对应 tag(基于地址高位 / shadow memory)
与 shadow memory 中存储的 tag 对比
不匹配则触发异常(report + abort),匹配则恢复相关寄存器继续运行
2. 堆内存插桩:识别 malloc/free 函数的调用点,动态插入 tag 分配和回收代码
分配内存时自动添加 tag
释放内存时自动清除 tag 信息
为返回地址高位打上 tag
3. 运行时检测:每次内存访问时,检查地址高位 tag 与 shadow memory 中的 tag 是否一致,不匹配则触发异常
支持检测的内存问题类型
注意:BinXO 二进制插桩当前主要支持堆类内存检测,栈类检测需使用源码编译插桩。
可检测的访存指令类型
BinXO 支持以下访存指令的检测:
标量指令:
A64_LDP_STP
A64_LDR_STR_IMMED
A64_LDR_STR_REG
A64_LDR_STR_UNSIGNED_IMMED
SIMD 指令:
A64_LDX_STX_MULTIPLE
A64_LDX_STX_MULTIPLE_POST
A64_LDX_STX_SINGLE
A64_LDX_STX_SINGLE_POST
【典型使用场景】
以下场景推荐使用 HWASAN + BinXO 进行内存问题检测:
1. C++ Native 占比高的应用:如音视频处理、游戏引擎、图像处理等大量使用 C++ 的应用
2. 集成第三方 SDK 的应用:第三方 SDK 通常只有编译好的 .so 文件,无源码可用
3. 线上踩内存问题频发:天网版本检测到大量踩内存问题,需要快速定位根因
4. 跨模块内存问题排查:多个模块间内存交互复杂,需要全量插桩检测
未使用 HWASAN + BinXO 时,开发者可能遇到以下问题:
【详细操作指南】
方式一:IDE 界面配置(推荐)
适用场景:调试/本地场景,DevEco Studio 6.1.0.830 及以上版本
步骤 1:创建 Native 工程
在 DevEco Studio 中创建包含 C++ Native 的代码工程。
步骤 2:开启 HWASAN
1. 点击菜单 Run > Edit Configurations
2. 进入 Diagnostics 选项卡
3. 勾选 Hardware-Assisted Address Sanitizer,开启 C++ 源码编译插桩检测

步骤 3:开启 BinXO(无源码二进制插桩)
从 DevEco Studio 6.1.0.830 版本开始,在同一界面勾选 BinXO check,开启无源码 .so 文件的 HWASAN 插桩检测。

步骤 4:构建 HAP 包
点击构建按钮,DevEco Studio 将自动完成 HWASAN 源码插桩和 BinXO 二进制插桩,生成检测包。
步骤 5:推包并运行测试
1. 将构建的 HAP 包推送到设备
2. 关闭应用 freeze 检测(依赖 HAP 包指定为 DEBUG 包):
aa attach -b <bundleName>3. 启动应用,执行相关用例
步骤 6:获取 HWASAN 日志
IDE 将自动收集 HWASAN 日志,可在日志视图中查看。

步骤 7:堆栈跟踪分析
1. 将 HWASAN 日志拷贝到 IDE 分析工具的左上角区域
2. 勾选 "解读堆栈跟踪"
3. 导入符号表信息
4. 点击 "开始分析"
5. 观测右下角的 报错栈 和 申请栈,直接定位问题

方式二:配置文件
适用场景:需要持久化配置或流水线构建
系统级配置
在工程目录下的 AppScope/app.json5 文件中添加 HWASAN 配置开关:
{ "app": { "hwasanEnabled": true }}模块级配置
在模块级 build-profile.json5 中添加构建参数:
{ "buildOption": { "externalNativeOptions": { "arguments": [ "-DOHOS_ENABLE_HWASAN=ON", "-DOHOS_ENABLE_BINXO=ON" ] } }}版本说明:
• DevEco Studio 6.1.0.830 以下版本:仅配置 -DOHOS_ENABLE_HWASAN=ON(仅源码插桩)
• DevEco Studio 6.1.0.830 及以上版本:同时配置两个参数,开启源码 + 无源码检测
方式三:命令行参数
适用场景:流水线/CI 构建
# DevEco Studio 6.1.0.830 及以上版本hvigorw assembleHar -p ohos-enable-hwasan=true -p ohos-enable-binxo=true# DevEco Studio 6.1.0.830 以下版本(仅源码插桩)hvigorw assembleHar -p ohos-enable-hwasan=true可选配置:排除特定 SO
部分 .so 由于技术原理限制不支持 BinXO 插桩,需要配置忽略以避免构建报错:
{ "buildOption": { "nativeLib": { "excludeSoFromBinXO": ["**/liblibrary.so"] } }}支持正则匹配,可在工程级或模块级 build-profile.json5 中配置。
【真实案例分析】
XXXX App 案例
XXXX App 使用 SourceLess HWASAN 后,帮助开发者发现了 libxxxa.so 中的访存问题。
原始日志:
Reason:HWASAN==appspawn==14177==ERROR: HWAddressSanitizer: allocation-tail-overwritten; heap object [0x00130004a600,0x00130004aa51) of size 1105Stack of invalid access unknown. Issue detected at deallocation time.deallocated here:#0 0x5ae366b394 (/system/asan/lib64/libclang_rt.hwasan.so+0x2b394) (BuildId: ace54fff777e92f7758544f77b2b931f9f1c7b55)#1 0x651af0b720 (/data/storage/el1/bundle/libs/arm64/libtocks.so+0xb720) (BuildId: 85c301da032d17f70c0e1d6bf4de932b58317447)#2 0x5aee4e6c84 (/system/asan/lib64/platformsdk/libace_napi.z.so+0x66c84) (BuildId: ccd61d3dec598e77f88de9fb142e4095)#3 0x7e86a5b5cc (/system/asan/lib64/module/arkcompiler/stub.an+0x5c85cc)#4 0x7e864a3320 (/system/asan/lib64/module/arkcompiler/stub.an+0x10320)#5 0x275bdd79f4 ([anon:ArkTS Heapsemi space]+0x179f4)allocated here:#0 0x5ae366b0e0 (/system/asan/lib64/libclang_rt.hwasan.so+0x2b0e0) (BuildId: ace54fff777e92f7758544f77b2b931f9f1c7b55)#1 0x651af12d54 (/data/storage/el1/bundle/libs/arm64/libtocks.so+0x12d54) (BuildId: 85c301da032d17f70c0e1d6bf4de932b58317447)#2 0x651af0b6b0 (/data/storage/el1/bundle/libs/arm64/libtocks.so+0xb6b0) (BuildId: 85c301da032d17f70c0e1d6bf4de932b58317447)#3 0x5aee4e6c84 (/system/asan/lib64/platformsdk/libace_napi.z.so+0x66c84) (BuildId: ccd61d3dec598e77f88de9fb142e4095)#4 0x7e86a5b5cc (/system/asan/lib64/module/arkcompiler/stub.an+0x5c85cc)#5 0x7e864a3320 (/system/asan/lib64/module/arkcompiler/stub.an+0x10320)#6 0x275bdd79f4 ([anon:ArkTS Heapsemi space]+0x179f4)从日志可以看出,堆内存[0x00130004a600,0x00130004aa51) 出现了越界访问。该块内存的申请的代码在 libtocks.so+0x12d54 的位置。

反汇编该 so,通过汇编可以看出,在 0x12d6c 的位置有一个越界访问。 如果开发者有源码, 可以更快的发现内存的问题。
检测效果:
无需获取第三方库源码
直接定位到具体 .so 文件中的问题
大幅缩短问题定位周期
【常见问题解答】
Q1:BinXO 二进制插桩有哪些规格限制?
Q2:HWASAN 使用 ARM64 地址高 8 位,会与应用冲突吗?
HWASAN 使用了 ARM64 虚拟地址的高 8 位作为 tag 存储。如果应用中也有动态库使用了高 8 位,会产生冲突导致误报。
规避方案:
1. 优先方案:该动态库针对 HWASAN 版本单独出一个二进制,关闭对地址高 8 位的使用
2. 次选方案:关闭该 .so 的 HWASAN/BinXO 插桩(影响:该 .so 的踩内存故障无法检测)
Q3:源码编译插桩遇到 `fixup not sufficiently aligned` 报错怎么办?
根因:HWASAN 源码编译要求栈变量 16 字节对齐,报错文件中有内联汇编开辟了未 16 字节对齐的栈变量,或定义了 pack 强制未 16 字节对齐的临时变量。
解决方案:
• 修改为 16 字节对齐
• 或在问题函数定义右侧添加修饰符:__attribute__((no_sanitize("hwaddress"))),该函数不进行 HWASAN 编译插桩
Q4:BinXO 插桩报错如何处理?
【参考文档】
• HWASAN 原理介绍:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-address-sanitizer-principle
• HWASAN 使用指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-hwasan#section31022911513
• HWASAN 最佳实践:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-hwasan-detection
• Clang HWASAN 开源文档:https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
总结:HWASAN + BinXO 方案通过二进制插桩技术,实现了无源码场景下的内存访问检测,大幅降低了踩内存问题的定位门槛。开发者只需在 DevEco Studio 中勾选两个选项,即可开启全面的内存检测能力,结合 IDE 集成的堆栈跟踪分析工具,能够快速定位内存问题根因,提升应用稳定性。
🔗 官网开发者学堂视频:https://developer.huawei.com/consumer/cn/training/result?type2List=201783644516849879&orderBy=1&courseType=5

🔗 社区 DFX 专题文章: https://developer.huawei.com/consumer/cn/forum/subject/2101218731402391001


【扫码加入 HarmonyOS DFX 技术交流群】





