Skip to content

P2 Startup Prelaunch Readiness v1 修正方案

根因证据

iOS 17 首个签名 Fixture 短 Session 完成了身份验证、CoreProfile 解码、House Arrest marker 取回与 timebase 比较:4 条 marker 完整,numer/denom 一致,drop high-water 为 0。时钟桥仍正确返回 outside-core-window

根因包含两层:CoreProfile channel 虽已执行 start,但受控 App 紧接着启动,设备端第一个可解码 CoreProfile chunk 晚于 Fixture marker;而当 CoreProfile 真正在 launch 前启动后,trace header 尚不包含未启动目标进程的 thread 归属。实测数据中 PERF_THD_Data (0x25010004) 持续提供 arg0=pid / arg1=tid,其语义与冻结 pykdebugparser 的 kperf_thread_info_sample 解码一致。

修正方案

  1. 受控启动且开启 Startup trace 时,CoreProfile 先启动并等待第一个非空 raw chunk。
  2. 首 chunk 立即写入本次 immutable raw Session,然后才发出 controlled launch。
  3. 后续消费复用同一 async iterator,不建立第二个 subscription,不增加 DTX owner。
  4. 超时、空 chunk、timebase 缺失时 fail closed,不启动一次无法校准的受控 Startup Session。
  5. decoder 仅对精确 0x25010004 事件承接 threadPid[arg1] = arg0;PID/TID 非正整数时忽略,不用相邻事件或时间距离推断归属。
  6. Fixture runner 显式接受 bufferMode=0|1,并把实际值写入每个 CoreProfile raw payload。先用单次 delayed Session 对比窗口完整性,只有 E4 更好的模式才进入重复性批次。

新门禁

text
prelaunchSourceReady = firstCoreProfileChunkObserved
                       AND firstChunk.byteLength > 0
                       AND firstChunk.timeConfig.numer > 0
                       AND firstChunk.timeConfig.denom > 0

semanticCalibrationLaunchAllowed = prelaunchSourceReady

if debugID == 0x25010004 AND arg0 > 0 AND arg1 > 0:
    threadPid[arg1] = arg0

bufferMode 是源配置而非业务指标;报告只比较同一模式的 Session,不混合聚合。

时钟桥原有公式不变:Fixture marker 还必须全部落入本 Session CoreProfile 解码后的最小/最大 Mach tick 窗口。

验收

  • Python 测试证明首个 raw chunk 已写盘后才调用 launch,且 adapter 只启动/订阅一次。
  • iOS 17 重跑 control 短 Session:marker 完整、timebase 一致、窗口覆盖、identity verified、drop=0。
  • iOS 18 在开发描述文件包含设备后执行相同验收。
  • 短 Session 通过后才进入 control / willFinish / didFinish 各至少 3 次。

回滚

移除 prelaunch 首 chunk readiness barrier,恢复原先 start 后立即 launch 的时序。该回滚会重新打开 outside-core-window 门禁,因此仅用于定位。

Perfowl · Performance Observer