Skip to content

P2 CoreProfile 启动阶段分析方案

目标与边界

在 pymobiledevice3 11.3.1 唯一 DTX owner 上启用 coreprofilesessiontap KDebug RAW v2,将 py-ios-device 2.4.26 的 App Launch Lifecycle 作为协议与事件映射参考,不引入其 runtime,不建立第二条 DTX socket。保持无侵入:不改包、不注入、不 Hook、不依赖 WDA/XCTest Runner。

原始字段与单位

  • 输入:core-profile.chunk.raw.chunk Base64 原始块、timeConfig.numer/denom、KDebug timestamp/arg0...arg3/tid/debugID
  • PID 归因:先读 RAW v2 header threadmap(tid,pid,process),再处理 TRACE_DATA_NEWTHREAD(0x07000004)TRACE_DATA_EXEC(0x07000008) 的运行时映射;跨 CPU/分块到达顺序不作为时间顺序。
  • 时间换算:timestampNs = floor(machTicks × numer / denom),使用整数算术,不使用 wall clock。
  • 全部启动指标 scope=processunit=milliseconds,计算层保留 Double,UI 格式化不回写。

阶段与公式

metricID阶段原始事件
ios.process.startup.system_interface_msSystem Interface Initialization0x1F07 dyld begin → 0x2BDC transition
ios.process.startup.static_runtime_msStatic Runtime Initialization0x2BDC transition → 0x1F07 static end
ios.process.startup.uikit_initialization_msUIKit Initialization0x2B87 code=90 arg0=0x32code=21
ios.process.startup.uikit_scene_creation_msUIKit Scene Creation0x2B87 多段 begin/end,保留重复 Span 并求和
ios.process.startup.will_finish_launching_mswillFinishLaunchingWithOptions()code=23code=24
ios.process.startup.did_finish_launching_msdidFinishLaunchingWithOptions()code=25code=26
ios.process.startup.scene_will_connect_mssceneWillConnectTo()code=300code=301
ios.process.startup.scene_will_enter_foreground_mssceneWillEnterForeground()code=312code=313
ios.process.startup.initial_frame_rendering_msInitial Frame Renderingcode=120x31CA0006
ios.process.startup.app_launch_total_msApp Launch TotalSystem Interface Initialization begin → 与 Initial Frame Rendering begin 配对的 0x31CA0006
text
spanDurationMs = (endTimestampNs - startTimestampNs) / 1,000,000
phaseTotalMs = sum(同 phase 所有完整 Span 的 spanDurationMs)
appLaunchTotalMs = initialFrameEndTimestampNs - systemInterfaceBeginTimestampNs

App Launch Total 按完整首尾锚点计算,不累加各阶段,因为阶段可以重叠。缺少 System Interface begin 时 App Launch Total 保持 null,即使能观察到后半段 Span 也不以局部耗时冒充总耗时。同名阶段用每线程 stack 配对,不覆盖重复 UIKit Scene Creation。

采集顺序与共享规则

选中 StartupTiming 时使用 controlled-cold-launch,避免把已有进程的前台切换误当成完整冷启动。顺序固定为:打开 owner/resolver → 以 py-ios-device 2.4.26 的 lifecycle 配置 bm=1 预启动唯一 CoreProfile adapter 并获得 start ACK → 通过同一 owner 的 ProcessControl 发送冷启动(OS_ACTIVITY_DT_MODE=1HIPreventRefEncoding=1DYLD_PRINT_TO_STDERR=1)→ 绑定返回 PID/generation → 启动其他 adapter。上述环境仅作用于受控启动进程,不改包、不重签、不注入。

同时选中 Frame Time 与 StartupTiming 时,只存在一个 CoreProfile adapter,filters = lifecycle filters ∪ presented-frame filter。所有 KDebug 记录先按 (machTicks, arrivalSequence) 排序,再做 PID/TID 归因;阶段 marker 再按 (timestampNs, arrivalSequence, actionOrder) 重建,同一 transition 固定先 END、后 BEGIN。

缺失、重置与质量语义

  • PID 未映射、时间基变化、RAW v2 header/对齐错误:missingunsupported-schema,不接受其阶段。
  • 只有 BEGIN 或 END:最终报告 partial,未闭合 Span 不参与时长;实时 wire 只发布闭合后的 candidate,不抢先发布不可更新的 partial。
  • 0x31CA0006 只有在同 PID/TID 已出现 code=12、能闭合 Initial Frame Rendering 时才是启动终点;此前的同码帧事件只计入 ignored,不得冒充 App Launch 终点。
  • 终点早于起点、逆序或溢出:丢弃该配对并计数,不写 0。
  • 未识别 lifecycle debugID:保留计数,不自行推断阶段。
  • 完整闭合但协议仍为私有实现线索:candidate;未经真机门禁不描述为可用。

产物与验收

产物:launch-spans.jsonllaunch-trace-report.json,并将 SHA-256、status、Span 数量纳入 foundation-delivery.json。验收覆盖完整序列、重复 Scene、PID 未映射、缺 BEGIN/END、分块增量解码、未知事件、双次回放 hash、唯一 CoreProfile adapter 与 launch 前 ready。真机 E4 另行验证 PID 归因、Initial Frame 闭合和各阶段数值非伪 0。

Perfowl · Performance Observer