在这里插入图片描述
在这里插入图片描述

一、前置思考

1.1 系统崩溃了,然后呢?

车机导航运行中突然卡死——如果什么都不做,车停不下来;如果无脑重启,正在写的数据全丢。系统需要一套"异常处理剧本":

异常发生 → 捕获现场 → 保存证据 → 分级处置 → 恢复/降级

1.2 容错的三层境界

① 防住: 代码层防御 (空指针检查、边界校验)
② 兜住: 内核层容错 (Watchdog 盯死锁、内存隔离)
③ 救回: 崩溃后恢复 (Panic 转储、重启、降级)

企业级目标: 任何异常都不能让设备"变砖"

1.3 关键机制一览

Panic: 内核发现不可恢复错误 → 终止系统(保现场)
Kdump: 崩溃瞬间的内存快照 → 事后离线分析(找根因)
Watchdog: 定时"喂狗",超时没喂 → 判定死锁 → 强制重启
异常恢复: 重启策略 / 数据保护 / 硬件故障隔离

二、核心原理

2.1 Panic 处理流程

触发源:
  → 内核空指针 / 越界
  → 断言失败 (BUG_ON)
  → 不可恢复硬件错误

处理流程 (panic()):
  ① 紧急打印: "Kernel panic - not syncing: ..."
  ② 中断屏蔽: 停止一切正常调度
  ③ 转储现场: 寄存器 / 栈 / 关键内存
  ④ Kdump: 若配置 → 加载捕获内核收集快照
  ⑤ 处置: 按 panic 参数 → 重启 / 挂起 / 进入救援

2.2 Kdump 崩溃转储

Kdump 原理:
  保留一块保留内存 (crashkernel=)
  → 平时放正常内核
  → 崩溃时: 保留区切换到捕获内核
  → 捕获内核把崩溃现场写到磁盘 (vmcore)

vmcore 内容:
  → 崩溃时所有 CPU 寄存器
  → 内核栈 + 进程栈
  → 内存全量/部分快照
  → 配合 crash/gdb 离线分析根因

2.3 Watchdog 看门狗

原理: 定时器 + 喂狗任务
  硬件看门狗: 外置芯片,超时不喂 → 硬件复位
  软看门狗 (lockup detector): 内核检测软死锁

软死锁检测:
  watchdog 线程周期性检查
  → CPU 长时间不调度 (soft lockup)
  → 中断长期被禁 (hard lockup)
  → 触发 NMI 处理 → panic 或 oops

喂狗机制:
  正常运行时周期喂狗
  → 系统挂起时无法喂狗
  → 看门狗超时 → 强制复位系统

三、源码/API 深度解析

3.1 应用层:崩溃捕获与上报

import { hilog } from '@kit.PerformanceAnalysisKit';
import { faultLogger } from '@kit.BasicServicesKit';

// 注册崩溃监听(应用层 FaultLog)
function setupFaultMonitor(): void {
  faultLogger.query(
    {
      beginTime: Date.now() - 24 * 3600 * 1000,
      endTime: Date.now(),
      maxEvents: 50
    },
    (err, logs) => {
      if (err) {
        hilog.error(0x0001, 'Fault', '查询失败: %{public}s', JSON.stringify(err));
        return;
      }
      for (const log of logs) {
        hilog.info(0x0001, 'Fault',
          '类型=%{public}s 时间=%{public}s',
          log.type, log.timestamp);
        // 上报到服务器做崩溃分析
        uploadFaultLog(log);
      }
    }
  );
}

// 应用崩溃类型
//  JS_ERROR: JS 运行时异常
//  CPP_CRASH: C++ 崩溃
//  APP_FREEZE: 应用无响应
//  SYS_FREEZE: 系统无响应

3.2 内核 Panic 路径(伪代码)

// 内核崩溃统一入口
void panic(const char *fmt, ...)
{
    // 1. 防重入: 已有 panic 则死循环等待
    static char buf[256];
    if (panic_cpu != PANIC_CPU_INVALID) {
        smp_send_stop();      // 停止其他 CPU
        for (;;) cpu_relax(); // 挂起等待复位
    }
    // 2. 记录崩溃信息
    bust_spinlocks(1);
    pr_emerg("Kernel panic - not syncing: ");
    // 3. 转储寄存器与栈
    dump_stack();             // 栈回溯
    show_regs(regs);          // 寄存器
    // 4. 触发 Kdump 收集
    if (kdump_enabled) {
        crash_kexec(regs);    // 切换到捕获内核
    }
    // 5. 写盘 + 处置
    emergency_restart();      // 按 panic_timeout 重启
}

3.3 Watchdog 检测(伪代码)

// 软死锁检测核心
static void watchdog_timer_fn(struct hrtimer *hrtimer)
{
    // 1. 检查当前 CPU 是否长时间未调度
    if (__this_cpu_read(watchdog_nmi_touch) == true) {
        __this_cpu_write(watchdog_nmi_touch, false);
        return;   // 正常喂狗
    }
    // 2. 超时判定
    duration = now - last_timestamp;
    if (duration > softlockup_thresh) {
        // 3. 软死锁 → 打印栈 + 触发处置
        pr_emerg("BUG: soft lockup - CPU#%d stuck");
        dump_stack();
        if (panic_on_soft_lockup) { panic(); }
    }
}

四、企业级实战落地

4.1 容错分级策略矩阵

异常等级 检测手段 处置策略 恢复目标
L1 可恢复 代码异常捕获 降级重试 不影响体验
L2 进程级 FaultLog 监测 重启进程 秒级恢复
L3 系统级 Watchdog 系统重启 分钟级恢复
L4 硬件级 Panic + Kdump 隔离部件 保核心功能

4.2 完整示例:异常捕获与容错演示

@Entry
@ComponentV2
struct KernelFaultDemo {
  @Local logs: string[] = [];
  @Local state: string = '系统运行中';

  private runPanicDemo(): void {
    this.logs = [];
    this.state = 'Panic 处置';
    this.log('💥 内核 Panic 处理流程演示');
    this.log('触发: 内核空指针解引用 (0x0)');
    this.log('① 紧急打印: "Kernel panic - not syncing"');
    this.log('② 中断屏蔽: 停止调度,保住现场');
    this.log('③ 转储现场: 寄存器 + 栈回溯');
    this.log('④ Kdump: 捕获内核收集 vmcore');
    this.log('⑤ 处置: panic=10 → 10秒后自动重启');
    this.log('→ 系统重启,vmcore 供离线分析 ✅');
  }

  private runWatchdogDemo(): void {
    this.logs = [];
    this.state = 'Watchdog 监测';
    this.log('🐕 看门狗机制演示 (软死锁检测)');
    this.log('正常: 每 5s 喂狗一次 ✅');
    this.log('任务 A 持锁不释放 (死锁):');
    this.log('  watchdog 线程检测: CPU 20s 未调度');
    this.log('  超过 softlockup_thresh (20s)');
    this.log('→ 打印 "BUG: soft lockup" + 栈信息');
    this.log('→ 按策略: panic_on_soft_lockup=1 → 重启');
    this.log('→ 系统恢复,死锁进程被清除 ✅');
  }

  build() {
    Column({ space: 12 }) {
      Text('🛟 内核异常捕获与容错').fontSize(20).fontWeight(FontWeight.Bold)
      Text('状态: ' + this.state).fontSize(13).fontColor('#4FC3F7')

      Row({ space: 8 }) {
        Button('Panic 流程').layoutWeight(1).height(40).fontSize(12)
          .onClick(() => this.runPanicDemo())
        Button('Watchdog').layoutWeight(1).height(40).fontSize(12)
          .onClick(() => this.runWatchdogDemo())
      }
      .width('100%')

      Scroll() {
        Column() {
          ForEach(this.logs, (l: string) => {
            Text(l).fontSize(11).lineHeight(18).fontColor('rgba(255,255,255,0.8)').width('100%')
          }, (l: string, i: number) => l + i)
        }.width('100%')
      }
      .layoutWeight(1).width('100%').scrollBar(BarState.Off)
    }
    .width('100%').height('100%').padding(16)
    .backgroundColor('#0D1B2A')
  }
}

4.3 车载/工业容错落地

车载系统:
  → 仪表盘崩溃 → 立即重启 + 黑名单记录
  → 中控死锁 → Watchdog 强制重启 (30s 内恢复)
  → 数据保护: 崩溃前定时落盘关键数据

工业设备:
  → 双机热备: 主备切换
  → 硬件看门狗: 外置芯片兜底
  → 故障隔离: 单部件异常不影响整机

五、问题排查与性能优化

问题 原因 解决
反复自动重启 Panic 未定位根因 分析 vmcore 找原因
重启后数据丢失 未及时落盘 关键数据同步写
Watchdog 误触发 喂狗任务被饿死 检查优先级、锁竞争
Kdump 收集失败 保留内存不足 调大 crashkernel 参数
恢复时间过长 重启链路慢 精简启动服务
偶发死锁难查 现场已破坏 开 lockdep 锁检测

5.1 容错体系搭建清单

1. 应用层: 全局异常捕获 + 崩溃日志上报 + 降级策略
2. 进程层: 关键进程守护 (拉起/重启)
3. 系统层: 配置 panic 参数、开 watchdog、预留 kdump 内存
4. 数据层: 关键数据双写/定时落盘/事务日志
5. 运维层: 崩溃聚合分析 + 根因修复闭环

六、高阶总结与最佳实践

  1. 捕获要快:异常发生第一时间锁定现场,拖延等于破坏证据。
  2. 转储要全:Kdump 快照是事后分析根因的唯一可靠依据,必须配置。
  3. 看门狗兜底:Watchdog 是最后防线——系统挂死也能自恢复。
  4. 分级恢复:能降级就降级,能重启进程就别重启系统,能重启系统就别变砖。
  5. 闭环分析:每次崩溃都分析 vmcore/日志 → 修复根因 → 回归验证。

一句话记住:容错四件套——Panic 保现场(终止不破坏证据)、Kdump 留证据(崩溃快照离线分析)、Watchdog 兜底(死锁强制恢复)、分级恢复(降级→重启进程→重启系统)——目标只有一个:任何异常都不让设备变砖。

Logo

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

更多推荐