外观
Build 55 CoreProfile 运行时冲突容错与按需采集降级
背景与问题
在 iPhone 15 真机测试中,暴露了两类关键架构与状态机问题:
- 预热与按需采集耦合:应用选择后的一次性准备与指标选择的按需启动耦合,导致修改指标时错误触发二次 Prepare 或 Prewarm 重启。
- CoreProfile 运行时错误引发 Session 崩溃:当系统底层的 kperf 产生并发占用或资源冲突时,抛出
RuntimeError: core-profile-source-busy,由于未作可降级异常处理,直接导致全 Session 崩溃为failed退出,且随后引发不必要的二次冷启动与重复启动尝试。
核心修复与状态机规范
- Prepare 与 Collect 完全解耦:
- App 选择后 Prewarm 一次性准备所有支持的 transport;
- 用户修改指标选择仅变更 MacApp 本地 Draft,不向 Sidecar 发送
prepare_app,不重启 Prewarm; - 点击开始采集时,仅按最终生效的
CapturePlan启动需要的数据源。
- CoreProfile 可降级错误分类与单会话降级:
- 新增
is_degradable_core_profile_error谓词,精准识别core-profile-source-busy、another recording owns kperf等硬件/驱动冲突,排除代码契约与语法 Bug; - 一旦 CoreProfile 遭遇可降级错误,将其置为
core_profile_unavailable_for_session = True,同步标记 StartupTiming 与 FrameTime 为 unavailable/partial,其余数据源(CPU、Memory、FPS、Network、Disk 等)继续采集; - 最终 Session 状态记为
completed或partial,严禁抛出未捕获 RuntimeError 或把 Session 标记为failed。
- 新增
- 严格单次冷启动与杜绝二次启动:
- Session 内一旦 CoreProfile 被标记不可用,禁止再次调用
CoreProfile.start(); - 受控冷启动严格恰好 1 次,启动早期遇 CoreProfile 失败直接降级,绝不重新拉起目标 App。
- Session 内一旦 CoreProfile 被标记不可用,禁止再次调用
- 能力事件延迟判定:
- CoreProfile 的
available=True延后至收到首个有效 chunk 后发出,杜绝start()返回但无数据时的虚假就绪。
- CoreProfile 的
验证与测试
- Python Sidecar:全量 388/388 通过,新增 6 项测试覆盖启动立即失败、早期排空失败、active stream 晚期失败过滤以及契约错误保留 fatal。
- Swift 客户端:全量 145/145 通过(含 3 项显式跳过,0 失败)。
- 打包与签名:生成 Build 55
Perfowl.app、ZIP 与 DMG,通过 Developer ID 严格验签、hdiutil verify与解包挂载校验。
交付产物与哈希
- ZIP:
MacApp/dist/Perfowl-internal-test-Build55-x86_64.zip(109,169,410 bytes,SHA-25611a3a19f3bfafa418817076a025110678eac8c2bffcc064b0b46fd8524666121) - DMG:
MacApp/dist/Perfowl-internal-test-Build55-x86_64.dmg(139,739,822 bytes,SHA-256e3243acd50beadc1774c4d7613cb980b7fe3716d410fd409addbbd168037a97e)