meow_crash 62781084; meow_svcd da6ebc66→605646c4(仅+68行上报挂点); 宿主5场景全过(上报链路/dmesg增量/无卡迁移/铁律验证/CLI)
4.4 KiB
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 缓冲整段搬入卡日志后删除(对齐 launcherlog_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 的预置方式)。