Files
MeowOS-For-R3P2/patch_v2/meow_crash/meow_crash.md
T

82 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# meow_crash — MeowOS 系统级崩溃捕获(二期组件)
> 状态:设计落盘 + 实现(agent 任务)。`meow_crash` 是 svcd 托管的小守护,负责把
> svcd 服务的异常退出与内核 oops/应用崩溃记录到日志,供事后排查。
> 定位见 FRAMEWORK_DESIGN §10(Supervisor 树 / 崩溃隔离)、APPS.md §4.5(统一日志系统)、
> devdocs/plan/SYS_BASELINE.md(svcd 子进程化,监护挂点)、devdocs/plan/APP_LOG_MANAGER.md。
## 1. 角色
`meow_crash` = 崩溃事件**记录器**(只读一条上报消息落盘,无共享内存、无 dlopen),
由 svcd 以 `fork+exec+setpgid` 托管(`/usr/bin/meow_crash` + `services.d/meow_crash.conf`
trigger=boot)。svcd 托管服务均为前台常驻(svcd waitpid),故 meow_crash
**不 daemonize**,svcd 崩则它是子进程被 waitpid 感知;它崩则 svcd 按 `on-fail` 重启它,
且其崩溃不影响 svcd(崩溃隔离)。
## 2. 捕获源
### ① svcd 服务异常退出(主源)
svcd 在 `reap_children()` 检测到**异常退出**(非 0 退出码 / 被信号杀,且非受控
stop/restart)时,经 AF_UNIX `/tmp/meow_crash.sock` 发**单行**文本(best-effort):
```
SVC <service_name> <exit|sig> <num> <epoch_sec> <uptime_sec>
```
- 全程非阻塞:客户端 socket 置 O_NONBLOCK;connect 失败即放弃(可短 poll POLLOUT
≤150ms 用于本地 listen backlog 排空,绝不重试)。**svcd 绝不被此带崩。**
- meow_crash 不在线 → 该条丢弃(符合「若 crash 不在线则跳过」)。
### ② 内核 oops / 应用崩溃(辅助,v1 不强求)
周期性(1s)`dmesg` 抓取,记录上次读取偏移(`g_dmesg_prev_len`),只扫**新增**段,
捕获含 `segfault`/`oops`(大小写不敏感)的行。环回/替换时全量扫并靠去重环防重复。
v1 不扫描 `/tmp` core 转储(不强求,留作后续)。
## 3. 落盘
- 有卡:`<card>/MeowOS/logs/crash_<bootts>.log` 追加写。`<bootts>` 复用
`/tmp/meow_bootts`(launcher 缓存的 boot 时间戳,`meow_` 前缀剥掉),同一 boot
会话跨进程共用;读不到则按 墙钟-uptime 计算并缓存。
- 无卡/写失败:`/tmp/meow_crash.log`(tmpfs,256KB 滚动,超出即重建)。
- 卡出现:`poll_card()` 把 /tmp 缓冲整段搬入卡日志后删除(对齐 launcher
`log_poll_card` 语义)。
- 总量:`log_cleanup_old()` 统计 logs/ 下 `meow_*` 与 `crash_*`,超过 1GB 按 mtime
删最旧(与 launcher 的 LOG_SIZE_LIMIT 同纪律,launcher 只管 meow_*,本守护并管)。
一行一条格式:
```
<epoch_sec> <uptime_sec> <source> <detail...>
```
- `source`:`svc`(来自 svcd)或 `dmesg`(内核行)。
- `detail`:`<name> exit=<code>` / `<name> signal=<sig>` / 内核行原文。
## 4. CLI(root 免鉴权,读文件,不依赖守护在线)
| 命令 | 说明 |
|---|---|
| `meow_crash dump` | 打印本 boot 崩溃清单(卡 `crash_<bootts>.log`;无卡/无文件回退 /tmp) |
| `meow_crash tail [N]` | 打印最近 N 条(默认 20,上限 100) |
| `meow_crash`(无命令) | svcd 拉起 → 前台常驻守护 |
`dump`/`tail` 把 epoch 转可读 `YYYY-MM-DD HH:MM:SS` 展示。
## 5. 测试钩子(宿主集成测试)
| 钩子 | 作用 |
|---|---|
| `--card <path>` / `MEOW_CRASH_CARD` | 覆写卡挂载点(宿主指向临时目录即走「有卡」路径) |
| `--sock <path>` / `MEOW_CRASH_SOCK` | 覆写上报 socket |
| `MEOW_CRASH_NOCARD=1` | 强制无卡(验证 /tmp 回退 + 后续迁移) |
| `MEOW_CRASH_DMESG_FILE=<path>` | 从文件读「假 dmesg」(宿主注入内核行) |
## 6. 边界 / 诚实标注
- **v1 不扫描 core 转储**(任务:「不强求」)。当前只做 svcd 上报 + dmesg 增量。
- **svcd 上报的 skip 语义**:受控 stop(stop_requested)与 restart 命令
(restart_pending)的退出**不**上报,只记真实异常退出(避免把管理员停服务当崩溃)。
- **dmesg 捕获**依赖设备 `dmesg` 可用(busybox;root)。宿主用 `MEOW_CRASH_DMESG_FILE`
注入。首扫会捕获本 boot 已存在的 crash 行(内核环在重启时清空,不会跨 boot 混入)。
- **固件打包需知 / 板载 conf 预置**:本任务按约束未改 `S89meow_svcd` 与固件脚本。
需在**打包/首启预置**阶段把 `patch_v2/meow_crash/meow_crash.conf` 落到
`/usr/data/meow/services.d/meow_crash.conf`(参照 S89 对 mdnsd/perf/power 的预置方式)。