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

Dart 堆栈符号化

概述

当 Flutter 应用在 Release 或 Profile 模式下发生卡死(AppFreeze)或崩溃(CppCrash)时,相关日志中通常会包含dart层的堆栈信息(libapp.so部分),但获取到的堆栈地址是十六进制偏移量,无法直接看到具体的 Dart 函数和行号。需要使用flutter symbolize工具将原始堆栈地址转换为可读的 Dart 源代码位置。

工具

  • 工具:flutter symbolize
  • 输入: 需要符号化的堆栈文件 + 符号文件
  • 输出: 符号化后的堆栈文件

命令

flutter symbolize-i<堆栈文件>-d<符号文件>-o<符号化后输出文件>

获取符号文件

符号文件在打包阶段生成。构建 HAP 包时追加--split-debug-info参数(意思是剥离调试信息,需要传入一个文件夹的路径),如:

flutter build hap--release--split-debug-info=./debug-info

打包时会将符号信息从libapp.so中分离出来,生成在指定目录下,如:./debug-info/app.ohos-arm64.symbols

生成堆栈文件

AppFreeze 日志、CppCrash 日志或 Hiprofler 抓取的 trace 文件中通常会包含dart层的堆栈信息(libapp.so部分),但需要转换为flutter symbolize工具可识别的格式。

原始堆栈格式(来自日志):

#00 pc 0000000000171698 /data/storage/el1/bundle/libs/arm64/libapp.so(301f78813ec57f68e57e8d5453ab0d89) #01 pc 00000000001537b4 /data/storage/el1/bundle/libs/arm64/libapp.so(301f78813ec57f68e57e8d5453ab0d89) ...

转换后的堆栈格式:

#00 abs 0000000000171698 virt 0000000000171698 libapp.so #01 abs 00000000001537b4 virt 00000000001537b4 libapp.so ...

说明:

  • #xx: 调用栈中的帧编号
  • pc: 程序计数器 - 表示指令指针地址
  • 0000000000xxxxxx: 十六进制地址
  • /data/storage/.../libapp.so: 共享库路径
  • (301f78813ec57f68e57e8d5453ab0d89): 构建指纹/哈希值

示例:AppFreeze 堆栈符号化

1. 准备输入文件

将转换后的堆栈保存为input.txt

#00 abs 0000000000171698 virt 0000000000171698 libapp.so #01 abs 00000000001537b4 virt 00000000001537b4 libapp.so #02 abs 0000000000281fe4 virt 0000000000281fe4 libapp.so #03 abs 000000000023e2b4 virt 000000000023e2b4 libapp.so #04 abs 000000000022ae88 virt 000000000022ae88 libapp.so #05 abs 0000000000234b8c virt 0000000000234b8c libapp.so #06 abs 0000000000237f2c virt 0000000000237f2c libapp.so #07 abs 0000000000237cd0 virt 0000000000237cd0 libapp.so #08 abs 0000000000278d3c virt 0000000000278d3c libapp.so #09 abs 0000000000146204 virt 0000000000146204 libapp.so #10 abs 000000000024df24 virt 000000000024df24 libapp.so #11 abs 0000000000146190 virt 0000000000146190 libapp.so #12 abs 00000000001460f8 virt 00000000001460f8 libapp.so #13 abs 00000000001458d4 virt 00000000001458d4 libapp.so #14 abs 000000000027d6a4 virt 000000000027d6a4 libapp.so #15 abs 0000000000179014 virt 0000000000179014 libapp.so #16 abs 0000000000178f54 virt 0000000000178f54 libapp.so #17 abs 0000000000178a40 virt 0000000000178a40 libapp.so #18 abs 000000000028dadc virt 000000000028dadc libapp.so #19 abs 000000000025bd20 virt 000000000025bd20 libapp.so #20 abs 00000000000dffc4 virt 00000000000dffc4 libapp.so #21 abs 00000000000ec878 virt 00000000000ec878 libapp.so #22 abs 00000000000ec808 virt 00000000000ec808 libapp.so #23 abs 00000000000ed5d4 virt 00000000000ed5d4 libapp.so #24 abs 00000000000dca20 virt 00000000000dca20 libapp.so

2. 执行符号化命令

flutter symbolize-iinput.txt-dapp.ohos-arm64.symbols-osymbols.txt

3. 查看符号化结果

symbols.txt内容如下:

#0 _MyHomePageState._dartFreeze (D:/Flutter/demo/flutter_dfx_sample/lib/main.dart:44:5) #1 _MyHomePageState._dartFreeze (D:/Flutter/demo/flutter_dfx_sample/lib/main.dart:41:3) #2 _InkResponseState.handleTap (D:/Flutter/flutter_flutter/packages/flutter/lib/src/material/ink_well.dart:1195:3) #3 GestureRecognizer.invokeCallback (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/recognizer.dart:345:24) #4 TapGestureRecognizer.handleTapUp (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/tap.dart:737:11) #5 BaseTapGestureRecognizer._checkUp (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/tap.dart:362:5) #6 BaseTapGestureRecognizer.handlePrimaryPointer (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/tap.dart:293:7) #7 PrimaryPointerGestureRecognizer.handleEvent (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/recognizer.dart:706:9) #8 PrimaryPointerGestureRecognizer.handleEvent (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/recognizer.dart:688:3) #9 PointerRouter._dispatch (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/pointer_router.dart:97:12) #10 PointerRouter._dispatchEventToRoutes.<anonymous closure> (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/pointer_router.dart:143:9) #11 _LinkedHashMapMixin.forEach (third_party/dart/sdk/lib/_internal/vm_shared/lib/compact_hash.dart:764:13) #12 PointerRouter._dispatchEventToRoutes (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/pointer_router.dart:141:18) #13 PointerRouter.route (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/pointer_router.dart:131:7) #14 GestureBinding.handleEvent (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:530:19) #15 GestureBinding.dispatchEvent (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:499:22) #16 RendererBinding.dispatchEvent (D:/Flutter/flutter_flutter/packages/flutter/rendering/binding.dart:473:11) #17 GestureBinding._handlePointerEventImmediately (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:437:7) #18 GestureBinding.handlePointerEvent (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:394:5) #19 GestureBinding._flushPointerEventQueue (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:341:7) #20 GestureBinding._handlePointerDataPacket (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:308:9) #21 GestureBinding._handlePointerDataPacket (D:/Flutter/flutter_flutter/packages/flutter/lib/src/gestures/binding.dart:300:3) #22 _invoke1 (lib/ui/hooks.dart:347:13) #23 PlatformDispatcher._dispatchPointerDataPacket (lib/ui/platform_dispatcher.dart:467:7) #24 _dispatchPointerDataPacket (lib/ui/hooks.dart:282:31) #25 _dispatchPointerDataPacket (lib/ui/hooks.dart:280:1) #26 stub InvokeDartCode+0xd4

符号化后可以清晰看到:

  • 崩溃发生在main.dart_MyHomePageState._dartFreeze方法
  • 具体行号:第 41 行和第 44 行
  • 调用链完整:从 Dart 层到 Flutter 框架再到 native 层

split-debug-info 参数影响

体积减少

加上--split-debug-info参数后,符号信息从app.so中分离,应用体积略有减小。

DevTools 无法连接

DevTools 依赖符号文件进行调试。添加此参数后会导致 DevTools 无法连接应用。建议在 Release 模式下使用。

性能无影响

测试表明开启和关闭该参数对 UI 和 Raster 性能无明显影响。

相关链接

  • Flutter 官方文档: https://docs.flutter.dev/reference/flutter-cli
http://www.jsqmd.com/news/588305/

相关文章:

  • 架桥记:耐达讯自动化CC-Link IE转EtherCAT的工业协议融合实战
  • 2026年新闻发稿高性价比服务商选型指南:行业趋势、适配标准与主流平台分析 - 发稿平台推荐
  • Windows平台MSVC编译的FFmpeg库
  • 植物大战僵尸游戏辅助工具:解锁9大隐藏功能提升玩家效率的完整指南
  • YOLO12保姆级教程:2025最新目标检测模型,5分钟开箱即用
  • 零基础学唱歌全套教程 声乐技巧入门到进阶资源
  • 1111111111111111111111
  • 飞书项目 vs. PowerProject:复杂软件研发场景深度对比评测
  • Bert模型
  • 【Git】TortoiseGit无法push远程仓库
  • Vibe Coding 有哪些实用技巧?这篇文章讲透工作流、提示词和避坑方法
  • 从语言到神经网络:人类表达的三次革命与AI的终极赋能
  • C++ Move 构造函数的优化原理
  • 海康云台 ISPAI 二次开发
  • 梦行云软件全系列
  • 【演化计算与抽样方法】构造新算法流程:从 AlphaEvolve 看 LLM × EA 融合范式
  • JL杰理AC696N开发板PWM波形生成与控制(1):频率、占空比
  • C++ 与 事务多版本并发控制(MVCC):在 C++ 存储内核中利用时间戳排序实现无锁读写冲突控制
  • MT5专业交易面板
  • 基于stm32单片机的仔猪喂饲系统设计
  • Git从入门到精通:原理、实战与企业级协作全攻略
  • React生态学习路线
  • 图片调色思路分享
  • 告别手动刷新:用快马生成自动化工具,高效锁定jxx登录页最新域名
  • 高性能负载均衡
  • KART-RERANK在互联网广告场景的应用:广告创意与搜索词的相关性优化
  • 游标分页与服务器端游标的对比分析
  • 工具篇:诊断延迟的利器——SHOW SLAVE STATUS详解
  • 【skill-creator 】技术解析:Claude Code 元技能系统的设计原理与核心特点
  • 如何让老旧苹果电脑重获新生:OpenCore Legacy Patcher完全指南