我是兰瓶Coding,一枚刚踏入鸿蒙领域的转型小白,原是移动开发中级,如下是我学习笔记《零基础学鸿蒙》,若对你所有帮助,还请不吝啬的给个大大的赞~

前言

说句实话:没有一行代码能第一次上线就“无崩溃、零卡顿、低功耗”。想把体验抛光,你必须手握一整套“能看、能量化、能复现、能定位、能修复”的工具链。本文给你一份可落地的鸿蒙(HarmonyOS / OpenHarmony)故障诊断与调试工具大全:从日志到 Trace,从崩溃到内存、从卡顿到功耗、从网络到渲染,再到工程化 CI/灰度守护。
  不玩虚的,流程化打法 + 常用命令 + 代码片段 + 清单表一应俱全,拿去就是干。🧰🔥

目录(可当作“排障地图”)

  1. 发现问题:指标、埋点与告警的第一现场
  2. 日志体系:HiLog 玩法与规范(含 ArkTS/Native 代码)
  3. 端侧 Trace:Bytrace/HiTrace 打开“时间显微镜”
  4. 性能剖析:HiPerf/Profiler(CPU、内存、线程、锁)
  5. 崩溃与 ANR:Faultloggerd、符号化、ANR 现场取证
  6. 内存问题:ASan/LSan、泄漏与碎片、对象热力图
  7. 图形与卡顿:帧率/丢帧、过绘、GPU & 渲染调试
  8. 网络与 I/O:抓包、重放、零拷贝链路检查
  9. 存储与文件系统:I/O 热点、慢查询、磨损与配额
  10. 功耗与温控:电流曲线、热点定位与策略回退
  11. 调试与自动化:HDC、单测/压测、灰度指标门禁
  12. 常见问题速查:现象 → 工具 → 命令 → 结论
  13. 上线前 50 条故障预防清单
  14. 附:常用命令/脚本/代码模板(可直接粘贴用)

温馨提示:文中命令/模块名以主流 HarmonyOS/OpenHarmony 工具命名为参考,具体路径或少量参数可能因版本/BSP 而异;请以你当前 SDK/设备为准调整。

1) 发现问题:别等用户来做 QA

最小可观测集(强烈建议内置)

  • 冷/热启动时长、首页可交互时刻(TTI)、关键页面 FPS
  • 崩溃/ANR 率(按版本/设备/场景维度)
  • 主线程/渲染线程卡顿(P95/P99 帧耗时)
  • 内存峰值 & 回落(场景切换前后)
  • 网络失败率、超时率、RT 分布
  • 电量消耗/温度曲线(关键路径)

埋点规范

  • 场景建模(登录、支付、直播、3D 战斗等),每个场景有 KPI 阈值;
  • 埋点含TraceID/SessionID,串起来还原一次完成路径;
  • 所有异常带版本号、构建号、符号版本,方便快速符号化。

2) 日志体系:HiLog 用出“层次感”

2.1 级别与域(LOG_DOMAIN/LOG_TAG)

  • DEBUG:开发调试,Release 默认关闭
  • INFO:关键状态变更、生命周期
  • WARN:可恢复的异常(超时、重试)
  • ERROR:功能失败、数据错乱
  • FATAL:不可恢复(会触发崩溃)

ArkTS 示例

// ArkTS:统一封装日志,按域/模块输出
const TAG = 'Login';
function logI(msg: string) { console.info(`[${TAG}] ${msg}`) }
function logE(msg: string, err?: Error) { console.error(`[${TAG}] ${msg} ${err?.message ?? ''}`) }

Native(C/C++)示意

#define LOG_DOMAIN 0x0201
#define LOG_TAG "NetCore"
#include "hilog/log.h"

HILOG_INFO(LOG_CORE, "Init ok, endpoint=%{public}s", ep);
HILOG_ERROR(LOG_CORE, "Dial failed, code=%{public}d", rc);

2.2 采集与过滤

# 全量(慎用)
hdc shell hilog

# 过滤 TAG/级别/进程
hdc shell "hilog | grep NetCore"
hdc shell "hilog -L W"           # 仅 WARN+

最佳实践

  • 少拼接字符串(性能/GC),使用参数化;
  • 敏感信息默认脱敏;
  • Release 版下发远程日志开关采样率,避免刷爆。

3) 端侧 Trace:Bytrace/HiTrace = 时间显微镜

目标:量化“谁在占时间”“什么时候堵住了”。

3.1 常用场景

  • 卡顿/掉帧:渲染线程与合成器同步、VSYNC 节奏
  • 页面慢:主线程阻塞、IO/锁竞争
  • 后台任务打断前台:调度与优先级

3.2 启动与标记

# 抓 10s 指定类别的 trace(示例类别)
hdc shell bytrace -t 10 gfx input view sched freq idle am wm

# 把结果拉出
hdc file recv /data/local/traces/trace.html ./trace.html

代码埋点(自定义 Trace 点)

// Native:在关键函数加标记
#include "hitrace/hitrace_meter.h"
void LoadScene() {
  StartTrace(HITRACE_TAG_APP, "LoadScene");
  // ... 资源加载/解析/绑定
  FinishTrace(HITRACE_TAG_APP);
}

看图要点

  • 长条:长时间执行/阻塞;
  • 交错:频繁上下文切换;
  • 空洞:等待 VSYNC/锁/IO。

4) 性能剖析:HiPerf/Profiler

4.1 采样/火焰图(CPU)

# 采样当前进程 30s
hdc shell hiperf -p <pid> --duration 30 -o /data/local/tmp/perf.data
hdc file recv /data/local/tmp/perf.data ./perf.data
# 本地用火焰图工具/IDE 打开 查看热点栈

关注:函数热点占比、锁等待、系统调用耗时;配合源码内联/逃逸优化。

4.2 内存与对象

  • ArkUI/ArkTS:IDE Profiler 查看对象分布/增长曲线;
  • Native:mallinfo/jemalloc 统计、峰值拍点、分配热图;
  • 大对象上传纹理/缓冲时记录资源 ID→字节数→生命周期

5) 崩溃与 ANR:拿到“第一手尸检报告”

5.1 崩溃收集(Faultloggerd/Crash)

  • 系统会生成 trace/minidump;抓取并符号化
# 常见崩溃目录(举例)
hdc shell ls /data/log/faultlog/temp/
hdc file recv /data/log/faultlog/temp/xyz.crash ./xyz.crash

符号化(Native)

  • 产物保留 *.so 的符号文件(*.so*.sym),使用工具 addr2line/llvm-symbolizer
  • 坚持“构建号→符号”一一对应,CI 自动归档。

5.2 ANR(无响应)

  • 取主线程堆栈、锁拥有者、IO 调用栈;
  • 对应 Trace 看是否被渲染/IO/锁卡住;
  • 复现场景:慢网/慢 IO/低电量/后台切前台

6) 内存问题:从“泄漏”到“碎片”

6.1 ASan/LSan(开发期构建)

  • AddressSanitizer:越界/重释放;
  • LeakSanitizer:泄漏检测(测试用 Release 关闭)。

6.2 泄漏定位套路

  1. 画热点曲线:哪一页/场景在涨
  2. Dump 对象图:谁在长期持有
  3. 看资源生命周期:纹理/缓冲是否在 onDestroy/onHide 释放
  4. 大图/音视频:是否重复 decode/未复用

ArkTS 容易忽视点

  • 全局单例/闭包持引用、定时器未清、事件监听未 off。

7) 图形与卡顿:FPS 不是唯一,抖动同样要命

7.1 帧率/掉帧诊断

  • 采集:渲染线程耗时、合成器等待 VSYNC、UI 布局时间;
  • 指标:P95/P99 帧耗时、最大连续掉帧;
  • 典型瓶颈:过绘、纹理上传、Shader 首遇编译、频繁状态切换

7.2 渲染侧抓手

  • 预热:Shader 预编译、资源 Warmup;
  • 批次/合批:同材质/同管线排序;
  • DRS:动态分辨率/降级策略(温控触发);
  • 过绘热图:在开发开关里可视化(不同色层数)。

8) 网络与 I/O:重放 > 空喊

8.1 抓包与重放

  • 端侧:网络日志 + 关键字段摘要(便于脱敏);
  • 服务端:保存协议样本,支持离线重放;
  • 重放关注:RT 分布、失败重试、重放幂等、缓存命中。

8.2 瓶颈与复现

  • 慢网场景(弱网/高时延/丢包),开关 丢包/限速 注入;
  • 端侧DNS/证书校验异常、握手超时;
  • 大包拆分、零拷贝链路是否生效。

9) 存储与文件系统:别让“小碎片”拖慢整机

  • I/O 热点:定位频繁读写的 Key/文件;
  • 顺序读合并小文件,避免“十万小包”;
  • 数据库慢查询/锁等待(加索引、批量事务);
  • 写放大与磨损(闪存):关键路径做合并与限速

10) 功耗与温控:体验的“隐藏 Boss”

  • 采集:不同场景的电流/温度曲线;
  • 分析:高耗电来源(高频唤醒、GPU 满载、频繁定位/扫描);
  • 策略:后台降频/降帧/降特效、批处理/合并唤醒(coalescing);
  • 温控回退:触发阈值→逐级关灯(阴影/粒子/DRS)。

11) 调试与自动化:把“人肉”变“机器人”

11.1 HDC(Harmony Device Connector)

hdc list targets            # 设备列表
hdc target mount <id>       # 选中设备
hdc shell                   # 进设备 shell
hdc file send a b           # 推送/拉取文件

11.2 自动化与门禁

  • 脚本化压测:关键场景一键跑(登录→首页→列表→搜索→详情→返回);
  • 绑定指标阈值:FPS、崩溃率、耗时、内存峰值超阈即打回
  • 符号/产物归档:构建号→符号→崩溃自动符号化→告警。

12) 常见问题速查表(摘录)

现象 首选工具 命令/方法 可能结论/动作
冷启动长 Bytrace、Profiler bytrace -t 10 am wm sched 初始化串行、IO 同步、首次编译/解压;改并行/懒加载/预热
首屏掉帧 Bytrace、渲染开关 bytrace -t 5 gfx view 过绘、纹理上传、布局重算;合批/缓存/异步上传
后台切前台崩溃 Faultlog、HiLog 拉取 crash、hilog 资源释放/恢复次序错误;补 onHide/onShow 资源管理
内存慢涨 Profiler、Dump 对象增长曲线 监听未解绑/单例强引用;加弱引用/生命周期钩子
网络偶发超时 网络日志、重放 弱网重放 DNS/握手失败、重试机制不合理;加超时/退避/缓存
温度拉升 电流/温度采集 机载或外接仪 长时间高负载;降帧/DRS/关特效/批量策略

13) 上线前 50 条故障预防清单(节选)

  1. HiLog 域/级别规范化,Release 关闭 DEBUG,敏感信息脱敏
  2. 关键路径埋点:启动、页面、网络、GPU、功耗、异常
  3. Bytrace 自定义 Trace 点已覆盖核心流程
  4. 性能基准脚本可一键跑,门禁阈值生效
  5. 崩溃自动上报 + 符号化链路,构建号对齐
  6. ANR 复现场景脚本(慢网、慢 IO、切前后台)
  7. 内存峰值 < 目标阈值,场景切换后回落达标
  8. Shader/资源预热,首遇卡顿消除
  9. 线程优先级/亲和度评审,主线程无耗时 IO
  10. 网络超时/重试/退避策略验证,弱网测通过
  11. 更新/热修签名校验,回滚演练通过
  12. 功耗/温控降级链路生效(阈值→关灯)
  13. 故障注入演练:断网/低存储/权限拒绝/证书失效
  14. 监控看板:崩溃率、卡顿率、内存、网络、功耗
  15. 版本灰度:机型/地区/渠道分批,异常自动“熔断”
    …(根据业务扩展到 50+)

14) 附:常用命令/脚本/代码模板

14.1 Bytrace 快速脚本(保存为 trace_10s.sh

#!/bin/sh
set -e
CATS="gfx input view sched freq idle am wm"
hdc shell "bytrace -t 10 $CATS"
OUT="/data/local/traces/trace.html"
hdc file recv "$OUT" "./trace_$(date +%H%M%S).html"
echo "Trace saved."

14.2 HiLog 过滤(常用管道)

# 只看自家 TAG,WARN+
hdc shell "hilog -L W | grep -E '\[NetCore\]|\[Login\]'"

14.3 ArkTS 卡顿观察:帧耗时上报

let last = Date.now()
globalThis.requestFrame(() => {
  const now = Date.now()
  const dt = now - last
  if (dt > 30) logW(`Frame long: ${dt}ms`)
  last = now
})

14.4 Native 自定义 Trace 埋点

#include "hitrace/hitrace_meter.h"
#define TRACE_SCOPE(name) TraceScope __ts(HITRACE_TAG_APP, name)
struct TraceScope { TraceScope(uint64_t tag, const char* n){StartTrace(tag,n);} ~TraceScope(){FinishTrace(tag);} uint64_t tag; };
void HeavyWork(){ TRACE_SCOPE("HeavyWork"); /* ... */ }

14.5 符号化(示意)

llvm-symbolizer -pretty-print -obj=./libxxx.so < backtrace.txt > symbolized.txt

结语:诊断是“能力”,不是“步骤”

做架构、写代码、拉性能、降功耗,其实都是一件事:建立可观测、可度量、可复现、可验证的闭环。当你把 HiLog、Bytrace、HiPerf、Faultloggerd、Profiler、功耗与网络工具串起来,你的产品质量和迭代速度会肉眼可见地上台阶。
  记住一句话:Bug 不可耻,隐藏才可耻。把它们请到聚光灯下,逐个击破。🕵️‍♂️🔦

(未完待续)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐