在这里插入图片描述

你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的App!
📌 关注本专栏《零基础学鸿蒙开发》,一起变强!
每一节内容我都会持续更新,配图+代码+解释全都有,欢迎点个关注,不走丢,我是小白酷爱学习,我们一起上路 🚀

前言

应用崩溃之后,很多开发者第一反应是去 Log 窗口翻记录。但 HiLog 输出的是你主动打印的日志,崩溃那一刻发生了什么、是哪一行代码出了问题——这些信息并不在那里。

HarmonyOS 有一套专门的故障日志机制,崩溃发生后会在设备上生成结构化的故障文件,记录时间、进程、故障类型和完整的调用堆栈。DevEco Studio 提供了直接获取这些文件的入口,就是 FaultLog。

这篇文章只做一件事:故意制造一个开发态崩溃,然后一步一步找到对应的 FaultLog,把里面几个最重要的字段看明白。

一、FaultLog 是什么,解决什么问题

应用在运行时发生未捕获异常(比如空指针、数组越界、JS 侧 Error)或者 Native 层信号异常时,HarmonyOS 系统会在设备本地生成一份故障日志文件,存放在设备的特定目录下。

这份文件记录的不是你写的 HiLog,而是系统自动捕获的崩溃现场:

  • 故障发生时间
  • 进程名称和 PID
  • 故障类型(比如 APP_FREEZE、JS_ERROR、CPP_CRASH)
  • 完整的线程调用堆栈

开发阶段可以通过 DevEco Studio 的 Device Manager 直接把这些文件拉取下来阅读。

这个入口不需要任何额外权限申请,是官方为开发调试阶段提供的标准工具链路。

二、把官方说法弄清楚

在进入实操之前,有几个前提条件值得先确认。

FaultLog 文件存储位置

根据官方文档,应用崩溃后生成的故障日志存储在设备的 /data/log/faultlog/faultlogger/ 目录下。普通应用没有直接访问这个路径的权限,只能通过调试工具读取。

DevEco Studio 获取路径

官方提供的开发态获取方式是:

通过 DevEco Studio → Device Manager → 连接设备后 → 进入 FaultLog 面板,直接查看当前设备上已生成的故障日志列表。

这是官方调试工具链内置的能力,无需手动 adb 命令也可以操作。

故障类型分类

官方文档中对故障类型有明确分类,开发阶段最常遇到的包括:

故障类型说明
JS_ERRORArkTS / JS 侧未捕获异常
CPP_CRASHNative C/C++ 层信号异常,如 SIGSEGV
APP_FREEZE应用无响应(ANR),主线程超时

本文只聚焦最直观的 JS_ERROR,也就是 ArkTS 侧的崩溃场景。其他类型后续可以单独展开。

三、制造一个可复现的崩溃

为了拿到一条真实的 FaultLog,需要先让应用崩起来。

这里用最简单的方式:在页面加载时主动访问一个 undefined 对象的属性,触发 ArkTS 运行时的未捕获异常。

目标: 页面 onPageShow 后立即崩溃,触发 JS_ERROR。

工程环境说明:

  • Stage 模型
  • ArkTS 语言
  • 无需额外 Kit 或权限配置
  • 在 Phone 或模拟器上均可复现

崩溃代码

新建一个普通 Page,在 aboutToAppear 里写入下面这段:

// CrashTestPage.ets
// 这段代码的目的是触发一个 ArkTS 运行时的未捕获异常
// 通过访问 undefined 对象的属性来模拟真实崩溃场景

@Entry
@Component
struct CrashTestPage {
  aboutToAppear(): void {
    // 故意制造:访问 undefined 上的属性,触发 TypeError
    let obj: Record<string, string> | undefined = undefined;
    // 下面这行会在运行时抛出未捕获异常
    console.log(obj!['key']);
  }

  build() {
    Column() {
      Text('这个页面会在 aboutToAppear 中崩溃')
        .fontSize(20)
        .margin(20)
    }
    .width('100%')
    .height('100%')
  }
}

几点说明:

aboutToAppear 是 ArkUI 组件的生命周期函数,在组件挂载之前执行。在这里制造异常,能够保证异常在页面完成渲染之前就抛出,是一个比较干净的崩溃触发点。

obj!['key'] 用了非空断言绕过编译器检查,但运行时 obj 确实是 undefined,所以会产生真实的 TypeError。

这段代码不依赖任何外部接口,直接复制进任何 Stage 模型工程的 Page 文件即可使用。

四、用 DevEco Studio 找到这条日志

崩溃触发之后,按下面步骤操作。

第一步:确认设备已连接

在 DevEco Studio 顶部工具栏或者菜单栏中,通过 View → Tool Windows → Device Manager 打开设备管理面板(也可以用快捷键,macOS 下通常在侧边栏直接显示)。

连接真机或者确认模拟器处于运行状态,设备列表中应该能看到对应设备。

第二步:进入 FaultLog

在 Device Manager 面板中,找到已连接设备,右键点击或展开设备节点,选择 FaultLog(部分版本 UI 略有差异,但入口名称是统一的)。

也可以通过顶部菜单:View → Tool Windows → FaultLog 直接打开。

第三步:找到对应的崩溃记录

FaultLog 面板会列出当前设备上的故障日志列表,每一条记录通常显示:

  • 时间戳:故障发生的精确时间
  • 进程名(Bundle Name):就是你自己的包名,比如 com.example.myapp
  • 故障类型:JS_ERROR、CPP_CRASH 等
  • 摘要:故障信息的第一行

根据时间和进程名定位到刚才触发的那条崩溃记录。

五、把日志里几个关键字段看明白

点开那条 JS_ERROR 记录,日志文件的内容大概是下面这个结构(根据官方文档描述整理,实际格式以设备输出为准):

Generated by HiChecker
Timestamp: 2024-xx-xx xx:xx:xx.xxx
Pid: 12345
Uid: 20010043
Process name: com.example.myapp
Reason: TypeError: Cannot read property 'key' of undefined

Stacktrace:
  at CrashTestPage.aboutToAppear (entry/src/main/ets/pages/CrashTestPage.ets:11:20)
  at anonymous (...)
  ...

几个真正需要看的字段:

Timestamp

故障发生的系统时间。用来对应你的操作时间,快速确认这条日志是不是你刚才触发的那一次崩溃,而不是更早留下来的历史记录。调试多次的情况下,时间是第一个筛选维度。

Pid / Process name

进程 ID 和进程名(通常是应用的 Bundle Name)。在同一台设备上安装了多个调试包的情况下,进程名能帮你确认日志属于哪个应用。

Reason

这是故障直接原因,也是最先要看的内容。上面例子里的 TypeError: Cannot read property 'key' of undefined 直接说明了是什么类型的异常以及在操作什么。

Stacktrace

调用堆栈,从崩溃发生点开始往上列出调用链。通常第一行就是出问题的那一行,对应到你的源文件名和行号。

堆栈的价值在于:当 Reason 是一个泛型的错误信息时(比如只说 Cannot read property),堆栈告诉你这个错误到底是从哪条执行路径走到的,帮助确认是哪个具体的业务分支出了问题。

六、几个容易忽略的地方

日志不是实时的

FaultLog 面板的内容不是自动刷新的,崩溃之后需要手动刷新或者重新打开面板,才能看到新生成的记录。如果崩了但面板里没出现,先刷新一次。

模拟器和真机都可以产生 FaultLog

不一定要用真机。标准模拟器上触发的崩溃同样会生成 FaultLog,可以用模拟器完成基本的调试流程。

堆栈行号依赖 Source Map

ArkTS 代码会被编译,如果堆栈里显示的是编译后的行号而不是源文件行号,需要检查工程的 Source Map 配置是否正常。DevEco Studio 在调试构建(debug build)下默认会保留 Source Map,可以确保堆栈能映射回源码。

同一个崩溃可能生成多条记录

如果连续触发了多次相同的崩溃,FaultLog 里会有多条时间不同但内容相似的记录。以时间戳区分,找最新的那条对应当前操作。

FaultLog 文件数量有上限

官方文档中提到系统会对故障日志的存储数量进行管理,旧的记录可能被自动清理。调试时建议及时拉取日志,不要依赖设备长期保留。

七、排查思路整理

遇到崩溃之后,建议按这个顺序处理:

  1. 先去 FaultLog,不要直接去 HiLog——HiLog 里没有崩溃堆栈,FaultLog 才是第一现场。

  2. 用时间戳定位这一次崩溃——避免把历史遗留的崩溃记录当成当前问题处理。

  3. 先看 Reason,再看 Stacktrace——Reason 告诉你是什么错,堆栈告诉你在哪里出的错。

  4. 堆栈第一行通常就是崩溃位置——找到对应的源文件和行号,直接去看代码上下文。

  5. 如果堆栈行号对不上源码——检查是否是 Release 构建、Source Map 是否存在。

  6. 如果 FaultLog 里找不到记录——确认设备连接正常、刷新面板、检查应用包名是否匹配。

开发经验总结

  • FaultLog 是 HarmonyOS 开发态调试的核心工具之一,DevEco Studio 提供了直接的面板入口,不需要手动操作文件系统。
  • 崩溃日志的核心字段是 Timestamp、Process name、Reason 和 Stacktrace,这四个字段基本可以覆盖大多数开发态崩溃的定位需求。
  • 本文只讨论了 JS_ERROR 这一类故障,CPP_CRASH 和 APP_FREEZE 的日志结构和分析方式有所不同,值得单独展开。
  • 如果你的项目里 ArkTS 和 C++ 混用,遇到 Native 崩溃时 FaultLog 同样是第一个去的地方,只是堆栈的格式不同,符号解析的方式也需要额外处理。

如果你正在调试一个偶发崩溃,不妨对比一下同一个 Reason 在不同时间的堆栈是否一致——如果堆栈每次都不一样,说明相同的错误来自不同的代码路径,这种情况往往比固定复现的崩溃更值得深挖。

❤️ 如果本文帮到了你…

  • 请点个赞,让我知道你还在坚持阅读技术长文!
  • 请收藏本文,因为你以后一定还会用上!
  • 如果你在学习过程中遇到bug,请留言,我帮你踩坑!
Logo

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

更多推荐