使用GWP-ASan定位地址越界问题
本原创文章帖发布在华为开发者联盟社区欢迎开发者前往访问评论交流更多与该内容相关讨论请点击原帖查看使用GWP-ASan定位地址越界问题-华为开发者话题 | 华为开发者联盟一、地址越界的定义与危害地址越界泛指程序对内存的错误访问例如堆内存释放后重用、栈内存退栈后重用、堆或栈的越界访问等。这类问题本质上是程序访问了“不该访问”或“已经失效”的内存区域属于典型的内存安全问题。地址越界问题的危害较大大部分情况下它会直接表现为应用闪退极个别情况下也可能表现为功能异常、数据异常、界面显示异常等功能性问题。相比闪退类问题功能性问题通常更容易被隐藏和忽略导致问题长时间潜伏在线上。同时地址越界问题具有很强的随机性。普通 Crash 日志或 Coredump 捕获到的往往不是内存被破坏的第一现场而是内存被破坏后在后续访问、释放或系统检测时暴露出来的二次现场。因此日志中看到的崩溃点不一定是真正的问题根因难以还原内存从申请、释放到异常访问的完整过程定位成本较高。GWP-ASan 正是用于解决这类问题的轻量级地址越界检测工具。它通过对堆内存分配进行采样在较低性能开销下检测释放后使用、堆越界访问、重复释放等典型内存错误触发的第一现场。相较于 HWASan/ASanGWP-ASan 无需额外插桩适配性能开销低于 5%更适合在大规模现网用户场景下运行用于发现难复现的地址越界类问题。目前GWP-ASan能检测的错误类型有故障类型含义Use After Free释放后使用Heap Buffer Overflow / Underflow堆上/下越界访问Double Free重复释放Invalid Left / Right Free指针非法释放详细检测原理可参考官网文档GWP-ASan检测原理 。二、GWP-ASan使用指南2.1 开启GWP-ASan检测方式一默认参数开启在app.json5中添加GWPAsanEnabled: true配置如下图所示开启GWP-ASan检测后如果应用发生地址越界问题且该内存块正好被GWP-ASan采样监控GWP-ASan会记录地址越界事件。方式二三方灰度支持开发者定制化开启GWP-ASan从API206.0版本开始开发者可通过如下参数去定制化开启GWP-ASan。从API246.1版本开始提供了可恢复模式在该模式下系统检测到地址越界故障后避免因检测机制本身导致进程崩溃。名称默认值是否必填说明APIROMalwaysEnabledfalse否true100%开启GWP-ASan与app.json5中GWPAsanEnabled标签功能一致。false1/128概率开启GWP-ASan在应用冷启动时候会判断是否开启。注意若在app.json5中设置了 GWPAsanEnabled将会覆盖该参数。206.0sampleRate2500否GWP-ASan采样频率。1/sampleRate的概率对分配的内存进行采样。建议值≥1000默认参数下性能开销小于5%。采样频率过小会显著影响性能若调整参数请开发者自行保证用户体验。206.0maxSimutaneousAllocations1000否最大分配的插槽数。当插槽用尽时新分配的内存将不再受监控。释放已使用的内存后其占用的插槽将自动复用以便于后续内存的监控。建议值≤20000每个插槽会额外占用约4.5KB内存默认参数下约占4.5MB过大可能导致VMA超限崩溃。206.0duration7否开启GWP-ASan检测天数默认值为7天。206.0isRecoverapi24 6.1版本false否该参数从 API 24 开始支持。用于控制应用在100% 开启 GWP-ASan 时是否以可恢复模式运行。true当 GWP-ASan 以 100% 概率开启时应用以可恢复模式运行。在该模式下系统检测到地址越界故障后避免因检测机制本身导致进程崩溃但对于已造成非法内存访问的错误应用仍可能发生崩溃。false当 GWP-ASan 以 100% 概率开启时应用以不可恢复模式运行。注意该参数只在“100% 开启 GWP-ASan”场景下生效1/128 概率开启场景默认为可恢复不受isRecover控制。默认值false。246.1接口具体使用方式可查看ohos.hidebug (Debug调试) 。三、使用场景3.1 开发态开发调试阶段以问题发现和复现效率优先。建议将应用配置为100%开启GWP-ASan检测以稳定暴露潜在内存问题。示例import { hidebug } from kit.PerformanceAnalysisKit; import { taskpool } from kit.ArkTS; import { BusinessError } from kit.BasicServicesKit; Concurrent function enableGwpAsanTask(): void { let options: hidebug.GwpAsanOptions { alwaysEnabled: true, sampleRate: 2500, maxSimutaneousAllocations: 5000, isRecover: false, // 不可恢复模式 }; hidebug.enableGwpAsanGrayscale(options, duration); } taskpool.execute(enableGwpAsanTask).then(() { console.info(Succeeded in enabling GWP-ASan.); }).catch((error: BusinessError) { const err: BusinessError error as BusinessError; console.error(Failed to enable GWP-ASan. Code: ${err.code}, message: ${err.message}); })该场景下每次应用启动均会使能GWP-Asan检测其中采样率为1/2500槽位数为5000检测到地址越界问题后应用会崩溃不会继续运行。若默认参数下问题仍较难复现可适当减小 sampleRate或增大maxSimutaneousAllocations以提升检测覆盖率。3.2 运维态当应用发布后出现疑似地址越界问题且默认 1/128 概率开启难以命中时开发者可通过 hidebug 接口并结合 duration 参数临时将应用切换为 100% 开启模式用于线上问题复现和定位。示例import { hidebug } from kit.PerformanceAnalysisKit; import { taskpool } from kit.ArkTS; import { BusinessError } from kit.BasicServicesKit; Concurrent function enableGwpAsanTask(): void { let options: hidebug.GwpAsanOptions { alwaysEnabled: true, sampleRate: 2500, maxSimutaneousAllocations: 1000, isRecover: true, // 可恢复模式 }; let duration: number 2; // GWP-ASan 检测天数 hidebug.enableGwpAsanGrayscale(options, duration); } taskpool.execute(enableGwpAsanTask).then(() { console.info(Succeeded in enabling GWP-ASan.); }).catch((error: BusinessError) { const err: BusinessError error as BusinessError; console.error(Failed to enable GWP-ASan. Code: ${err.code}, message: ${err.message}); })该场景下在指定时长内应用每次启动都会使能GWP-ASan检测其中采样率为1/2500槽位数为1000检测到地址越界问题后不会崩溃继续运行。同样地如果问题难以复现也可以适当的调整sampleRate和maxSimutaneousAllocations。四、GWP-ASan日志4.1 日志获取4.1.1 开发态方式一通过DevEco Studio获取日志DevEco Studio会收集设备/data/log/faultlog/faultlogger/路径下的进程崩溃故障日志到FaultLog下根据进程名和故障和时间分类显示。获取日志的方法参见DevEco Studio使用指南-FaultLog 。方式二通过hdc获取日志需打开开发者选项日志默认都落盘至 /data/log/faultlog/faultlogger 下。在开发者选项打开的情况下开发者可以通过hdc file recv /data/log/faultlog/faultlogger D:\命令导出故障日志到本地。故障日志文件名格式为gwpasan-com.example.sampleapplication-20020209-20260416234001285.log其中 com.example.sampleapplication 表示应用包名20020209 表示应用 UID20260416234001285 表示故障发生时间。4.1.2 运维态方式通过HiAppEvent接口订阅HiAppEvent给开发者提供了故障订阅接口详见HiAppEvent介绍 。参考订阅地址越界事件ArkTS 或订阅地址越界事件C/C 完成地址越界事件订阅并通过事件的external_log 字段读取故障日志文件内容。4.2 日志规格GWP-ASan的日志格式如下会展示越界类型Use After Free、Double Free、Overflow等。以下示例为典型的Use-After-Free问题日志包含内存块的分配、释放及违规访问的调用栈信息。五、实战案例5.1 原始日志*** GWP-ASan detected a memory error *** Use After Free at 0x5b41761010 (16 bytes into a 40-byte allocation at 0x5b41761000) by thread 18502 here: #0 0x5b13f1a6d0 (/system/lib64/libwm.z.so0x1da6d0) (BuildId: xxx) #1 0x5b13f18d5c (/system/lib64/libwm.z.so0x1d8d5c) (BuildId: xxx) #2 0x5b13f1a24c (/system/lib64/libwm.z.so0x1da24c) (BuildId: xxx) ...... 0x5b41761010 was deallocated by thread 18502 here: #0 0x5a859859d4 (/lib/ld-musl-aarch64.so.10x1579d4) (BuildId: xxx) #1 0x5a859853ac (/lib/ld-musl-aarch64.so.10x1573ac) (BuildId: xxx) #2 0x5b13f1a6cc (/system/lib64/libwm.z.so0x1da6cc) (BuildId: xxx) #3 0x5b13f18d5c (/system/lib64/libwm.z.so0x1d8d5c) (BuildId: xxx) ...... 0x5b41761010 was allocated by thread 18502 here: #0 0x5a859859d4 (/lib/ld-musl-aarch64.so.10x1579d4) (BuildId: xxx) #1 0x5a85985110 (/lib/ld-musl-aarch64.so.10x157110) (BuildId: xxx) #2 0x5a859a773c (/lib/ld-musl-aarch64.so.10x17973c) (BuildId: xxx) #3 0x5a86f731a4 (/system/lib64/libc.so0xb31a4) (BuildId: xxx) #4 0x5b13f1a724 (/system/lib64/libwm.z.so0x1da724) (BuildId: xxx) #5 0x5b13f18d5c (/system/lib64/libwm.z.so0x1d8d5c) (BuildId: xxx) ......5.2 问题分析拿到一份 GWP-ASan 日志后首先看日志中的故障类型和关键调用栈。从日志首行可以看出该问题是 Use After Free即释放后使用异常访问地址为 0x5b41761010。继续看释放栈可以发现异常访问和释放动作都发生在线程 18502 中且报错栈和释放栈都指向 libwm.z.so 的相近位置• 报错栈#0 libwm.z.so0x1da6d0• 释放栈#2 libwm.z.so0x1da6cc重点分析这两个偏移对应的代码逻辑。通过 addr2line -Cfpie libwm.z.so 0x1da6d0 0x1da6cc 定位源码行关键代码如下1、对报错栈 libwm.z.so0x1da6d0 进行分析后发现这里对应一处三元运算符逻辑。代码会根据迭代器 it 是否指向 ownPropList.end() 来决定 insertPair 的值。2、对释放栈 libwm.z.so0x1da6cc 进行分析后发现这里做了容器erase的操作。问题此时已经比较明确erase(it) 会删除 it 指向的元素删除后原来的 it 会失效不能再继续使用。但当前代码在 erase(it) 之后又继续使用 it 参与三元判断并在特定分支下解引用 *it从而触发 Use After Free。5.3 修复建议需要避免在 erase(it) 后继续使用原来的迭代器 it。如果后续还需要使用该元素内容应在 erase 前先保存如果需要继续遍历则使用 erase 返回的新迭代器。六、聚类规则应用程序在不同版本或同一版本的不同时间可能因为同一根因产生多份 GWP-ASan 故障日志。但日志中的部分信息会随着版本、时间、地址随机化等因素发生变化导致开发者难以快速判断这些日志是否属于同一类问题。同时GWP-ASan 日志中通常同时包含系统侧和应用侧调用栈。如果不做过滤和归一化处理容易受到系统库栈帧、BuildID 等信息干扰不利于开发者快速聚焦应用侧问题。因此为避免重复分析多份故障信息提高应用故障问题的分析效率可以根据故障类型和业务相关调用栈对日志进行聚类。判断多份日志是否属于同一问题主要基于以下两个维度1、地址越界的故障类型。2、业务相关调用栈过滤基础库后的栈顶前两帧。通过上述信息可以对问题进行初步定界。6.1 步骤一提取故障类型在GWP-ASAN日志中故障类型根据原始日志中包含at的行提取。6.2 步骤二标准化栈信息提取故障类型后需要对日志中的调用栈进行筛选、清洗和标准化避免易变信息影响聚类结果。主要规则如下1. 去除易变信息行号、相同的BuildID和绝对地址。2. 过滤系统栈帧系统库栈帧通常以“/system/lib”或“/system/lib64”为起始字符。3. 保留业务相关栈帧保留业务so路径作为关键特征。例如原始栈帧内容标准化后栈帧内容#0 0x5b181acd48 (/lib/ld-musl-aarch64.so.10x169d48) (BuildId: 2e2fbc21511b76f80bdcc5ad5bcc0e79)忽略基础库#1 0x661be0e870 (/data/storage/el1/bundle/libs/arm64/libentry.so0x4e870) (BuildId: 5bc0684c2c3fc90841c2498efe1af4fd4792e5a8)/data/storage/el1/bundle/libs/arm64/libentry.so0x4e8706.3 步骤三提取聚类特征与聚类在完成标准化后根据不同故障类型提取关键栈作为特征故障类型关键栈帧提取规则Use After Free释放栈过滤基础库后取栈顶的前两帧so名相对偏移Buffer Overflow报错栈Double Free第一次释放栈第二次释放栈Invalid Free报错栈最终聚类特征为故障类型关键栈帧

相关新闻

LIN总线:汽车低速网络的低成本通信之道

LIN总线:汽车低速网络的低成本通信之道

1. 为什么汽车电子需要LIN总线? 当你按下车窗升降按钮时,可能不会想到这个简单动作背后藏着精妙的通信设计。在汽车电子领域,像车窗控制、雨刷调节、座椅加热这类功能,既不需要毫秒级响应,又对成本极其敏感。这时候&am…

2026/6/30 12:29:29阅读更多 →
告别被动跳闸!全屋园区智慧配电升级,真正实现用电主动防患

告别被动跳闸!全屋园区智慧配电升级,真正实现用电主动防患

家里莫名跳闸、老旧线路暗藏起火隐患、工厂设备好好的突然停机、小区公摊电费算不清……相信不管是普通家庭住户,还是园区物业、工厂设备负责人,都或多或少被用电安全与运维难题困扰过。传统空气开关几十年没变过,核心逻辑始终是“出事再断电…

2026/6/30 12:29:29阅读更多 →
2026年AI简历+面试工具深度横评:5个硬核标准 × 6款产品实测,找到你的求职副驾

2026年AI简历+面试工具深度横评:5个硬核标准 × 6款产品实测,找到你的求职副驾

📌 摘要:本文面向正在求职的应届生、转行者和 0-5 年职场人,解决「AI 简历/面试工具太多、不知道怎么选」的痛点。基于 CSDN 质量分标准,定义 5 个硬核评测维度,实测 2026 年主流 AI 求职工具,输出可落地的…

2026/6/30 12:29:29阅读更多 →
WindowsCleaner:彻底解决C盘空间不足的终极清理工具

WindowsCleaner:彻底解决C盘空间不足的终极清理工具

WindowsCleaner:彻底解决C盘空间不足的终极清理工具 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否经常遇到Windows电脑C盘爆红的困扰&#xf…

2026/6/30 13:29:37阅读更多 →
3小时掌握NHSE:动物森友会存档编辑器的终极使用指南

3小时掌握NHSE:动物森友会存档编辑器的终极使用指南

3小时掌握NHSE:动物森友会存档编辑器的终极使用指南 【免费下载链接】NHSE Animal Crossing: New Horizons save editor 项目地址: https://gitcode.com/gh_mirrors/nh/NHSE 还在为《集合啦!动物森友会》中繁琐的收集过程而烦恼吗?NHS…

2026/6/30 13:29:37阅读更多 →
从仿真到实战:基于Multisim的数字钟设计与调试全流程解析

从仿真到实战:基于Multisim的数字钟设计与调试全流程解析

1. 数字钟设计基础与Multisim入门 第一次用Multisim做数字钟仿真时,我对着闪烁的数码管发呆了半小时——明明电路连接没问题,就是显示乱码。后来才发现是译码器的消隐引脚没接高电平。这种"低级错误"恰恰是新手最容易踩的坑。 数字钟作为经典…

2026/6/30 13:29:37阅读更多 →
微信聊天记录备份终极指南:如何安全保存珍贵对话数据

微信聊天记录备份终极指南:如何安全保存珍贵对话数据

微信聊天记录备份终极指南:如何安全保存珍贵对话数据 【免费下载链接】WechatBakTool 基于C#的微信PC版聊天记录备份工具,提供图形界面,解密微信数据库并导出聊天记录。 项目地址: https://gitcode.com/gh_mirrors/we/WechatBakTool 在…

2026/6/30 13:29:37阅读更多 →
Java for 循环

Java for 循环

Java for 循环专业详解 一、定义与定位 for 是Java最常用的计数型循环,适用于循环次数明确、需要自增/自减控制变量的场景,结构紧凑,将循环初始化、循环条件、迭代更新三部分统一写在头部,可读性优于while。 二、标准for循环完整语…

2026/6/30 13:29:37阅读更多 →
Nintendo Switch大气层完整安装指南:解锁游戏系统的终极方案

Nintendo Switch大气层完整安装指南:解锁游戏系统的终极方案

Nintendo Switch大气层完整安装指南:解锁游戏系统的终极方案 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 想要为你的Nintendo Switch解锁无限可能吗?大气层&…

2026/6/30 13:24:37阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/30 4:03:30阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/30 4:36:27阅读更多 →
为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南 【免费下载链接】Destiny-2-Solo-Enabler Repo containing the C# and XAML code for the D2SE program. Included is also the dependency for the program, and image asset. 项目地址: https://gitcode…

2026/6/30 0:02:58阅读更多 →
第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

1. PowerPoint 2010基础操作全攻略 刚接触PowerPoint 2010时,很多人会被它复杂的界面吓到。其实只要掌握几个核心区域,就能快速上手。我最开始用PPT时,经常找不到功能按钮在哪,后来发现主要操作都集中在顶部功能区。 工作窗口主要…

2026/6/30 0:02:58阅读更多 →
XGBoost超参数实战:从理论到调优策略

XGBoost超参数实战:从理论到调优策略

1. XGBoost超参数基础认知 第一次接触XGBoost时,我被它那密密麻麻的参数列表吓到了。这感觉就像面对一架波音747的驾驶舱——每个按钮都可能有神奇的效果,但按错了就可能坠机。经过多年实战,我发现其实掌握十几个核心参数就能解决90%的问题。…

2026/6/30 0:02:59阅读更多 →