如何使用 Device Status⁺ 在 iPhone 本机上读取和分析 sysdiagnose 日志

Author: Neo Huang
最后更新: 2026-08-16 20:15:15
标签:

Index

每一部 iPhone 都带有一个被称为 sysdiagnose 的“黑匣子”——这是一份系统诊断归档,当出现问题时,苹果工程师会首先查看它。同时按住两个音量键和侧边按钮大约一秒钟,iOS 就会在后台悄悄记录一份。即使经过压缩,它仍然有数百兆字节之大,里面塞满了 ioregsmcDiagnosetaskinfo、崩溃报告以及电池化学数据。

问题在于:它从来都不是为你准备的。 解压后,它是数千个文件和数万行纯文本。你想要的价值被埋藏在 IODeviceTree.txt 的第 10,000 行,或者 IOService.txt 中某个 NVMe 控制器节点内。即使是有经验的开发人员也需要十分钟才能找到它。

Device Status⁺ 将这堵文字墙变成了一屏易于阅读的卡片——完全在设备本地进行处理,不会上传任何一个字节。本指南将介绍其诊断日志分析器 (Diagnostic Log Analyzer) 的工作原理,从捕获 sysdiagnose 到阅读卡片,以及为什么它在执行此操作时不会导致你的手机崩溃。

什么是 Device Status⁺?

Device Status⁺ 是由 Space-Time Transformation Technology Co., Ltd. 开发的一款免费系统监控应用。它需要 iOS 17.0+,可在 iPhone、iPad、Mac(M 系列)、Apple Vision Pro 和 Apple Watch 上运行。除了实时的 CPU、内存、存储、电池和网络仪表板外,它还内置了专门用于 sysdiagnose 归档的诊断日志分析器,以及用于日常电池分析的电池日志分析器(将在单独的指南中介绍)。

下文描述的所有操作都在本地进行。导入界面对此说明得很清楚:“所有处理均在设备上完成。不上传任何内容。

sysdiagnose 到底是什么?

sysdiagnose 是整个系统在特定时间点的快照。由硬件按键组合触发,它会收集:

  • ioreg 设备树转储(IODeviceTree.txt, IOService.txt
  • SMC(系统管理控制器)读数和 smcDiagnose
  • taskinfo 进程快照
  • 汇总的崩溃报告(.ips
  • 电池化学 plist 和 NAND 磨损快照
  • 网络、Wi-Fi 和蓝牙状态

结果会生成一个 sysdiagnose_YYYY.MM.DD-...tar.gz 文件,解压后可能包含超过 2,400 个条目以及 PAX 扩展标头。在内存受限的 iPhone 上,显而易见的方法——“将所有内容读入内存,然后解压”——会因为 OOM(内存不足)而崩溃。所以分析器并没有这样做。

第 1 步:捕获 sysdiagnose

最困难的部分不是分析,而是获取文件。Device Status⁺ 提供了一个图文并茂的指南(LogCollectionGuideView),引导你完成每一次点击:

  1. 同时按住两个音量键 + 侧边按钮大约一秒钟,在触感反馈后松开——这将触发 sysdiagnose。
  2. 继续正常使用手机,等待大约 10 分钟完成收集。
  3. 打开设置 → 隐私与安全性 → 分析与改进 → 分析数据,并搜索 sysdiagnose
  4. 打开文件 → 共享 → 存储到文件 → 回到 Device Status⁺,点击 + 导入。

为了将“查找条目”这一步缩短至零,该指南提供了两个一键快捷方式:安装一个快捷指令(iCloud 链接),以及通过快捷指令 Scheme 直接跳转到“分析与改进”面板

第 2 步:导入而不导致内存崩溃

这就是工程实现发挥关键作用的地方。SysdiagnoseArchiveExtractor 运行一个两阶段的流式管道,仅需几千字节的缓冲内存即可处理 800 MB 的归档。

第 1 阶段 —— gunzip。 使用 zlib 的 inflateInit2(16 + MAX_WBITS) 进行支持 gzip 的解码,输入文件被 mmap 映射(按需分页,从不常驻内存),输出以 64 KB 的块写入临时的 .tar 文件。峰值内存仅仅是缓冲区大小。

第 2 阶段 —— untar。 一个手写的状态机逐个解析 USTAR / GNU / PAX 标头,并将每个条目写入磁盘。它支持 GNU 长文件名(L 类型)、每个条目和全局的 PAX 扩展标头(x / g)以及 base-256 大小字段。归档文件永远不会被完整地保存在内存中。

健壮性的细节同样重要:

  • 磁盘空间预检查。 在执行 gunzip 之后,一旦知道了确切的 .tar 大小,分析器会在继续之前检查 volumeAvailableCapacity,以确保满足“一个 tar 文件 + 安全余量”——不会因为解压了一半而导致存储空间爆炸。
  • 路径安全。 isSafeRelativePath 会拒绝绝对路径、内嵌的 \0 以及 .. 路径遍历。任何操作都不会写入沙盒之外。
  • 完整性检查。 CRC 和 ISIZE 验证留给 zlib;截断或损坏的 gzip 会以可读的错误呈现(inflateFailed / truncatedArchive),而不是静默挂起。
  • 临时 .tar 总是被清理。 无论成功还是失败,defer 都会将其移除,因此不会留下数百兆字节的垃圾文件。

在解压过程中,UI 会显示一个进度叠加层,区分“正在解压 gzip(已展开 N MB)”和“已提取 N 个文件”——让你确信它确实在工作。

通过共享扩展一键导入

你可以完全跳过“文件”应用的中转。sharelog 扩展可以直接从“分析数据”列表中识别 sysdiagnose_*.tar.gz。至关重要的是,该扩展不进行任何解析——它的内存预算太小,无法解压 sysdiagnose。它只是将文件复制到 App Group 容器(ShareInbox/)中,向 App Group 的 UserDefaults 写入一个待处理信号,并通过 devicestatus URL Scheme 唤醒主应用。然后由主应用执行占用大量内存的提取工作。最终的感觉就像是一键完成。

第 3 步:读取设备概览

SysdiagnoseOverviewParser 从三个来源拼凑出设备的身份:

  • remotectl_dumpstate.txt 中的第一个 Properties: {…} 块 → 型号、操作系统、序列号、UDID、ChipID、SoC 平台、区域代码等。
  • ioreg/IOService.txt 中的 "product-name" → 营销名称(例如 iPhone 17),内置了 ProductType 到名称的回退机制。
  • 根文件夹名称 → 捕获时间戳(同时支持 +0800 偏移量和本地时间格式)。

每个字段都同时保留了其原始键和友好的标签(例如 ChipID / 33104),因此你可以将卡片与原始日志行进行交叉核对。

第 4 步:探索七个类别

这是核心的产品决策:没有纯文本转储,仅显示从每个文件中提取的关键指标作为卡片。 SysdiagnoseCategoryConfig 将数千个文件映射到七个互斥的类别中,列出拥有专用提取器的文件。这就是为什么角标数字等于你实际将看到的卡片数量——你永远不会点击进去后发现空空如也。

类别 你会看到的内容(卡片)
系统 设备标识、操作系统版本、捕获信息、安全启动状态、夜览
处理器 SoC 平台、CPU / 核心数、GPU、内存 Die、控制器、模块供应商、无线网络与蜂窝网络(来自 IODeviceTree)
电池与电源 电池与温度 (SMC)、电池健康度、化学诊断 (ACAM)、循环次数 (BDC 汇总)、耗电量最高的进程
存储 存储 / 系统卷、APFS 容器、NVMe SSD 硬件与 I/O、NAND 使用量 / 磨损均衡 / Band 分布 (ASP 快照)
内存 内存使用情况 (vm_stat)、占用内存最多的进程 (ps)、内存压力 (jetsam)
连接性 Wi-Fi、蓝牙、网络可达性
崩溃与错误 汇总的崩溃报告 (.ips)

只有内部人士才会提取的细节

  • 电池化学 (ACAM)。 它将 com.apple.batteryintelligence.batteryalgorithms-OnDeviceACAM-state.plist 解析为三个卡片:
    • 电池标识 —— 电芯序列号、是否为原装、充电电压限制。
    • 活性材料 —— 活性材料保留率(QLi / Qn / Qp:锂离子 / 负极 / 正极的可用比例)。
    • 老化与电阻 —— SEI 生长、裂纹 / 相变损耗、电极电阻。 这些微观健康指标通常只存在于苹果的内部工具中。
  • 存储硬件(NVMe + NAND)。 它从 IOService.txt 中的 NVMe 控制器节点提取单元类型(SLC / MLC / TLC / QLC)、页面大小、固件版本、读/写操作和错误。它从 ASPSnapshots/asptool_snapshot.log 中提取 NAND 启动 / 电源循环次数、终身读/写量、磨损均衡和 Band 分布。换句话说:你拥有哪种类型的 NAND 闪存单元、写入了多少数据,以及还剩多少寿命。
  • 芯片识别。 IODeviceTree 中的 chip-id 是小端序十六进制;提取器将其转换为对工程师友好的“T 编号”(例如 T8130),将晦涩的十六进制转化为可读的芯片代号。

值得了解的提取技术

  • 大文件绕过预览上限。 taskinfoIODeviceTree.txtIOService.txtasptool_snapshot.log 远超 4,000 行的预览限制。提取器在解析之前会读取完整文件,因此绝不会遗漏功耗排名、芯片节点、NVMe 控制器和 NAND 健康信息。
  • 多文件折叠。 每日的电池循环 CSV 文件(BDC_Daily_*.csv)折叠为一个“电池循环”卡片(最新值);每一个 .ips 崩溃日志折叠为一个汇总的“崩溃报告”卡片。
  • 跨文件关联。 循环次数会同时从 SMC 当前的 B0CT 值和 BDC 历史记录中读取,然后进行比较。

历史记录与持久化

每次导入都会存放在 Application Support/SysdiagnoseCases/<serial_timestamp> 下,元数据保存在 SysdiagnoseHistoryStore 中。重新导入相同的归档会复用现有的提取结果(通过 caseId 去重)。列表支持滑动删除和全部清除,并且能够瞬间重新打开——因为它只重新解析概览,而从不重新运行提取。

内置的三项承诺

  1. 完全离线,在设备本地运行。 从解压到提取,不会发起任何网络请求。
  2. 可读性高于性能。 每次解析的终点都是一张卡片,而不是原始文本。原始字段会保留以供交叉核对,但默认处于隐藏状态。
  3. 生产级健壮性:
    • 路径遍历保护、磁盘空间预检查、tar 标头验证、确保临时文件被清理。
    • 文件渲染护栏: SysdiagnoseFileContent 将文本限制为 512 KB / 4,000 行,将 CSV 限制为 1,000 行;提取器会以读取完整文件作为后备方案,因此单个文件永远不会撑爆内存。
    • 人类可读的错误转换(将 inflateFailed 转换为“归档已损坏或下载不完整”)。
    • 跨启动路径兼容性(同时处理新的相对路径和旧的沙盒绝对路径)。

总结

诊断日志分析器并不试图显示 sysdiagnose 中的所有 2,000 多个文件。它回答了你真正关心的问题——我的硬件配置是什么?我的电池健康吗?我的存储磨损程度如何?最近为什么会崩溃?——并为你提供清晰、可共享、可验证的答案。

捕获有引导,导入只需一键,解压绝不会耗尽内存,屏幕上只显示卡片。如果你需要长期的陪伴工具——从分析日志中获取的每日电池健康趋势——请参阅电池日志分析器指南