外观
P2 Startup 挂起启动屏障 v1 方案
问题收敛
- “CoreProfile 首个非空 chunk 先于 launch”可以保住 control,但首 chunk 需等待约 0.8–1.1 秒,会在目标 App 开始前消耗设备端缓冲。
- 6 组过滤集将 4 轮中 3 轮的 300 ms marker 恢复到窗口内,证明事件密度是关键变量;但固定等首 chunk 仍使窗口余量不稳定。
- stop 后 6 秒与 15 秒诊断均可继续收到 binary,直接增大 drain 上限只放大等待,不解决启动时序。
新时序
text
kill existing target when cold launch requested
→ ProcessControl launch(StartSuspendedKey=true), obtain PID
→ CoreProfile setConfig/start on the existing DTX owner
→ receive CoreProfile start acknowledgement
→ start the single raw consumer
→ ProcessControl send SIGCONT to the same PID
→ persist launch.requested.raw at resume boundary
→ verify Bundle ID / executable / PID identity
→ decode and persist immutable raw chunkslaunch.requested.raw的起点从“创建挂起进程”调整为“恢复执行”,与 App 实际开始运行对齐。- 挂起、CoreProfile 和恢复均使用同一 pymobiledevice3 DTX owner 下的 ProcessControl/CoreProfile channel,不增加第二 socket。
- 不改包、不重签普通被测 App、不注入、不依赖 WDA/XCTest。
- 挂起创建、源启动或恢复任一失败时 fail closed,并尝试终止未恢复的 Fixture 进程。
原始字段与计算
text
sourceActivationReady = coreProfileSetConfigSent
AND coreProfileStartSent
AND coreProfileStartAckObserved
resumeAllowed = targetSuspended AND sourceActivationReady
launchRequestMonotonicNs = sigcontDispatchMonotonicNs
observedRunningMs = (observedRunningMonotonicNs - launchRequestMonotonicNs) / 1,000,000raw/Session 新增或锁定:
| 字段 | 语义 |
|---|---|
launchBarrierMode | process-control-suspended-v1 |
sourceActivationReady | CoreProfile start ack 是否先于恢复 |
resumeSignal | 固定 SIGCONT |
launchRequestBoundary | 固定 process-resume |
- Startup 阶段 Mach 耗时公式不变;首 chunk 允许在 resume 之后到达,但 start ack 必须先于 resume。
- 指标聚合只接受同一
launchBarrierMode、过滤集、bufferMode 和算法版本。 - 缺失保持
null/—,不补 0。
验收
- E2:测试证明挂起 PID 先于 CoreProfile、start ack 先于
SIGCONT、resume 先于launch.requested.raw,且全程单 owner。 - E4:iOS 17/18 各执行 control、willFinish 300 ms、didFinish 300 ms 单轮;先要求
insideCoreWindow=true。 - 只有单轮稳定后才执行 3×3 因果门禁;未通过前 mapping 保持 candidate。
回滚
关闭 process-control-suspended-v1 屏障并恢复首非空 chunk readiness。历史 Session 通过 launchBarrierMode 与 launchRequestBoundary 区分,不回写。