diff --git a/patch_v2/files_app/files b/patch_v2/files_app/files index b3f4a05..1bc696e 100755 Binary files a/patch_v2/files_app/files and b/patch_v2/files_app/files differ diff --git a/patch_v2/hello_app/hello b/patch_v2/hello_app/hello index 0f76929..ce5a24a 100755 Binary files a/patch_v2/hello_app/hello and b/patch_v2/hello_app/hello differ diff --git a/patch_v2/meow_launcherd/meow_launcherd b/patch_v2/meow_launcherd/meow_launcherd index 2f18786..0ebc32b 100755 Binary files a/patch_v2/meow_launcherd/meow_launcherd and b/patch_v2/meow_launcherd/meow_launcherd differ diff --git a/patch_v2/sdk/meow_ui.h b/patch_v2/sdk/meow_ui.h index d2a2f7b..0a21284 100644 --- a/patch_v2/sdk/meow_ui.h +++ b/patch_v2/sdk/meow_ui.h @@ -692,7 +692,7 @@ void meow_sheet_free(meow_sheet *s); /* §9 应用日志(统一日志 API,M2.51 最小可用版) */ /* ============================================================ */ /* app 只需一行 meow_log();SDK 管「写哪/怎么写/过滤/降级/上限」: - * - 路径:/apps//logs/<启动时间>_.log + * - 路径:/<启动时间>_.log(MEOW_LOG_DIR 已含包名分层 logs/<包名>) * (目录不存在 mkdir -p,按 app 分目录),每次启动=新文件,同一次启动内 O_APPEND 追加; * - 级别过滤:lvl < meow_log_get_level() 丢弃;默认 MEOW_LOG_INFO; * - 格式: [] message\n; diff --git a/patch_v2/sdk/meow_ui_gfx.c b/patch_v2/sdk/meow_ui_gfx.c index bc4c8ca..a25a41f 100644 --- a/patch_v2/sdk/meow_ui_gfx.c +++ b/patch_v2/sdk/meow_ui_gfx.c @@ -1135,6 +1135,7 @@ static void meow_gfx_load_multifont(void) int meow_ui_init(const meow_ui_opts *opts) { if (g_init_ok) return 0; + meow_log_install_exit_handler(); /* M2.78:SIGTERM/SIGINT 兜底写 exit: 日志 */ int fw = 0, fh = 0; if (opts) { fw = opts->width; fh = opts->height; } diff --git a/patch_v2/sdk/meow_ui_internal.h b/patch_v2/sdk/meow_ui_internal.h index 2d22645..241b396 100644 --- a/patch_v2/sdk/meow_ui_internal.h +++ b/patch_v2/sdk/meow_ui_internal.h @@ -102,6 +102,9 @@ void meow_gfx_mark_dirty(int x, int y, int w, int h); * 解除后由调用方一次 flush 原子上屏,避免覆盖层与 App on_tick 重绘同帧两刷频闪。 */ void meow_gfx_flush_hold(int on); +/* M2.78:安装 SIGTERM/SIGINT 退出日志兜底处理器(meow_ui_log.c;meow_ui_init 调用)。 */ +void meow_log_install_exit_handler(void); + /* 绘制期裁剪(MEOW_APP_SDK.md §3,2026-08-31):当前 clip 矩形内才写像素,默认全屏。 * meow_widget_draw(w) 画任何控件前 push 该控件矩形、画完 pop——任何控件(含 W_CUSTOM) * 画不出自身边界,根治自定义画布越界脏区。可嵌套(入栈/出栈,push 与当前 clip 求交)。 diff --git a/patch_v2/sdk/meow_ui_log.c b/patch_v2/sdk/meow_ui_log.c index d0981c4..73b4fc0 100644 --- a/patch_v2/sdk/meow_ui_log.c +++ b/patch_v2/sdk/meow_ui_log.c @@ -35,6 +35,7 @@ #include #include #include +#include #include /* 单行消息上限(超长截断) */ @@ -70,6 +71,8 @@ static int g_log_fallback = 0; /* 1=无卡/写失败,降级 stderr */ static int g_log_open_tried = 0; /* 是否已尝试开首个文件(只试一次,失败则降级) */ static unsigned long g_write_count = 0; /* 累计写入次数(周期总量清理节流) */ +static void log_open(void); /* 前向声明(log_sig_exit 在其定义之前使用) */ + /* 由 g_log_base + g_log_seq 重建当前文件路径(seq=0 无后缀,>0 追加 _)。 */ static void log_rebuild_file(void) { @@ -118,6 +121,28 @@ static void log_init(void) } } +/* 退出日志兜底(M2.78):App 被 watchdog 返回键 SIGTERM 时走默认终止,跳过正常 + * 路径的 meow_log("exit"),日志只剩 start。SDK 在 meow_ui_init 安装本处理器: + * SIGTERM/SIGINT → 直接 write 一条 exit:(绕过 stdio 缓冲)→ exit(0)(干净码)。 + * App 自装处理器(如 hello 画 BYE)会覆盖本处理器,其 exit(0) 路径不受影响。 */ +static void log_sig_exit(int sig) +{ + if (!g_log_open_tried) { g_log_open_tried = 1; log_open(); } + if (g_log_fd >= 0) { + char line[128]; + int n = snprintf(line, sizeof line, "%llu [%s] INFO exit:%s\n", + (unsigned long long)meow_ui_time_ms(), g_app_id, + sig == SIGTERM ? "sigterm" : "sigint"); + if (n > 0) { ssize_t w = write(g_log_fd, line, (size_t)n); (void)w; } + } + exit(0); +} +void meow_log_install_exit_handler(void) +{ + signal(SIGTERM, log_sig_exit); + signal(SIGINT, log_sig_exit); +} + /* mkdir -p:逐分量 mkdir(已存在 EEXIST 视为成功)。返回 0=成功,-1=失败。 */ static int log_mkdir_p(const char *path) {