直接用 log show 查应用崩溃根源的关键是抓崩溃前的真实行为痕迹,如权限被拒、内存越界、系统服务超时等错误信号,而非仅搜索“crash”;需结合 Bundle ID 或进程名筛选 error/fault 级日志,锚定时间窗口,聚焦 Termination Reason、Exception Type 等字段,并与 .crash 文件交叉验证。
直接用 log show 查应用崩溃根源,关键不是搜“crash”这个词,而是抓它崩溃前的真实行为痕迹——比如权限被拒、内存越界、系统服务超时、插件加载失败等。这些信号往往藏在 error/fault 级别日志里,且紧邻崩溃时间点。
锁定目标应用的错误上下文
先确认应用 Bundle ID(如 Safari 是 com.apple.Safari,微信是 com.tencent.xinWeChat),再用以下命令提取它最近 1 小时内触发的所有错误线索:
log show --predicate 'senderImagePath contains "YourAppBundleID" AND level >= error' --last 1h- 把
YourAppBundleID换成实际 ID;若不确定,可用log show --predicate 'process == "AppName"' --last 1h(如process == "WeChat") - 重点关注
Termination Reason、Exception Type、Code Signature、Authorization等字段出现的行
捕获崩溃前的关键前置事件
很多闪退不是突然发生的,而是由前面几步异常连锁引发。例如:网络请求超时 → 主线程卡死 → Watchdog 杀进程 → 崩溃报告生成。用时间锚定能还原链条:
- 查到崩溃大致时间后(比如 2026-07-07 14:22:35),执行:
log show --start "2026-07-07 14:20:00" --end "2026-07-07 14:25:00" --predicate 'senderImagePath contains "com.apple.Safari" OR process == "Safari"' | grep -E "(error|fault|deny|timeout|kill|watchdog)" - 这样可筛出崩溃窗口内所有可疑信号,比只看 crash 文件更早发现诱因
- 特别留意
deny(沙盒权限拒绝)、timeout(I/O 或网络阻塞)、watchdog(看门狗强制终止)这类词
区分系统级干扰与应用自身缺陷
第三方插件、登录项、辅助功能扩展常伪装成目标应用崩溃。用子系统过滤可剥离干扰:
- 只看 Safari 自身逻辑:
log show --predicate 'subsystem == "com.apple.WebKit" AND level >= error' --last 30m - 排查插件冲突:
log show --predicate 'eventMessage contains "plug-in" OR eventMessage contains "extension" OR eventMessage contains "bundle"' --last 1h - 检查辅助功能是否拖垮主线程:
log show --predicate 'subsystem == "com.apple.accessibility" AND level == fault' --last 1h
导出并交叉验证崩溃证据
单条日志容易误判,需和崩溃报告(.crash 文件)互证。终端快速提取关键段落:
- 列出最近的 Safari 崩溃文件:
ls -t ~/Library/Logs/DiagnosticReports/Safari_*.crash 2>/dev/null | head -n 3 - 提取该文件中异常类型和堆栈头几行:
grep -A 5 -B 2 "Exception Type\|Termination Reason\|Thread 0 Crashed" "$(ls -t ~/Library/Logs/DiagnosticReports/Safari_*.crash | head -n1)" - 再用
log show查同一时间点的系统响应:log show --start "2026-07-07 14:22:30" --end "2026-07-07 14:22:40" --predicate 'process == "kernel" OR process == "WindowServer"' | head -n 20
不复杂但容易忽略:log show 的时间范围必须精确到分钟级,且 senderImagePath 比 process 更可靠——因为同一个进程名可能对应多个不同 bundle,而 senderImagePath 能锁定具体二进制来源。


















