Skip to content

历史未执行草案;当前门禁与下一动作以最新 devlog 为准。原始会话标识仅保存在私有证据。

P4 / Build 74 · Instruments.app 与 Perfowl 启动订阅参数差分审计 ​

方案日期:2026-09-24。角色:Research / Test AI。Owner 已完成 Instruments.app 真机实验,本批优先分析现有 .trace 和原始 Session,不得擅自重跑、改变产品代码或宣布 E4 PASS。结论提交 Lead AI 独立审计。

0. 实验目的和冻结状态 ​

回答五个彼此不同的问题:

  1. Apple Instruments 中是否确实取得目标 App 的启动 Total 和 Initial Frame Rendering?具体是哪条 timeline / instrument、哪套 START/END 语义?
  2. Instruments.app 使用的模板选项与 Perfowl 已实际下发到设备的 CoreProfile 配置,有哪些已证明差异?哪些配置因 .trace 没有公开导出而仍然未知?
  3. Perfowl 缺少首帧 END,是过滤器没覆盖、设备端丢失、解码/归属失败、终点语义不同,还是停止等待过早?
  4. 是否能从现有 Perfowl 29 个原始 CoreProfile chunk 找回此前漏解的真实终点?离线重放不能凭空恢复设备未录下的事件。
  5. 若确实存在配置差异,应该只针对哪一个参数开展后续最小受控试验?不得把未经验证的候选改动直接合入 main。

主线 main=4c1e424acaf6c8ee2b0941d3091b207e671fcf90;产品对应 Build 74 1ec94623f3623d37be206f82e114a6b441547db5;已验收签名 ZIP SHA-256 3a557cc0c0c666f90736c34fa9b633adb646a92a55ecfdae095c41f349a5dbc1。本批不改产品、不重签包。Phase C Hybrid Total FROZEN,C0 当前来源可行性 CLOSED / NO PROVEN PATH,C1/C2 禁止启动。

1. 确定证据:Perfowl 实际参数,不靠源代码推测 ​

冻结的 设备 A / 系统版本留私有证据 真机 Session:

~/Library/Application Support/Perfowl/Sessions/SESSION_B/

精确读取 collector-core/raw-events.jsonl 中第一条 core-profile.chunk.raw 的 rawPayload.effectiveCoreProfileConfig 和 coreProfileConfigSignature;验证此配置与随后各 chunk 一致;输出脱敏后的 actual-config.json。

已知应核验而非直接视作 Instruments 原生配置的值:

字段该 Perfowl Session 实测待审计风险
DTX 服务com.apple.instruments.server.services.coreprofilesessiontap使用底层服务不等于复用完整 Instruments 模板
事件类别 kdf20x1F070000, 0x2B870000, 0x2BDC0000, 0x31CA00004 组 acceptedFilters,已经覆盖首帧相关类别,不能声称完全漏订首帧过滤器
缓冲模式 bm0项目适配器注释称 py-ios-device App Launch Lifecycle 使用 bm=1;不等于已证实 Apple Instruments 使用 bm=1
sampling triggerfalse与 kperf 竞争相关,未经证明不可开启
callstack depth csd0主要影响调用栈;不是首帧 END 缺失的默认归因
rp100对照原生录制设置是否有真正同义项
tc / ta / tk从 actual-config.json 精确摘录对照 pymobiledevice3 默认配置及候选差异
ring experiment默认 OFF,除非 Session 原始配置证明其他值不得猜测设备缓冲容量

关键源码:MacApp/Sidecar/perfowl_collector_core/launch_trace.py 中 core_profile_filters() 和 startup_trace_codes.json;adapters.py 中 CoreProfileRawAdapter._make_stream();realtime.py 中 dedicated_lifecycle_options()、prewarm / activation / completion-grace;startup_channel.py。

过滤器红线:startup_trace_codes.json 目前 referenceFilters 为 17 组、acceptedFilters 为 4 组;先查历史缩减实验中的设备 buffer overflow 原因。不得未经容量预算就把 17 组全部打开,否则可能让缺失更严重。

2. 已知负例的时间线 / 不得误判 ​

同一 Session 的启动请求约在 2026-09-24 北京时间 09:44:21.215;约 09:44:27.511 报 startup-completion-grace-expired,该 4.061 秒是延迟进入的完成等待,不是 App 总启动超过 4 秒。

  • 29 个 CoreProfile chunk、原始约 91 MB、离线重放能力可用。
  • 已归属目标生命周期记录 25 条,7 个阶段为候选;sceneWillEnterForeground() 留有未配对 BEGIN,Initial Frame Rendering 完全未观察到。
  • traceEndTimestampNs=null;totalDurationMs=null,不能把 815.41ms 的阶段累计冒充 Total。
  • 启动窗口内有 1 次设备端 lost-event marker;标记只证明存在丢失现象,不能证明恰好丢了首帧 END。
  • 超时后仍有 3 个 CoreProfile chunk 到达。分析其精确 kernel timestamps、内容及是否进入最终离线报告,不允许仅依据 host 收包时间推断 App 在该时刻才完成绘制。
  • 同 Session 有 154 条 FrameLifetime,但尚无跨源原生同 epoch 和 surface→target PID、时间有效前台身份的证明,不能把第一条 FL 当合法 Hybrid END。

3. A 阶段:接收并归档 Owner 已完成的 Instruments 实验 ​

  1. 在本机合理目录定位最新 .trace,记录每个文件路径、大小、mtime、SHA-256;不要改写原件。可以查询 mdfind,然后范围限定在 Owner 保存目录。已知此前 Desktop/Documents/Downloads 和 Spotlight 没有发现新 trace,只查到旧 artifacts/frame-source-poc/host-frame-lifetimes.trace,这个旧 trace 不得冒充本次 App Launch 结果。
  2. 如 Instruments 窗口仍有未保存录制,应将原始录制另存到私有归档;不能自动替 Owner 在未确认的界面发起新录制。若只有截图或测试报告,明确证据等级 UI_ONLY,不能自称具备 .trace 级证据。
  3. 分轮记录:模板名、Instruments/Xcode 版本、设备型号/iOS、App 是否相同、App 是 Instruments 主动启动还是工具启动后手动打开、冷/热启动、采集前是否已进入 recording、Total 和 Lifecycle 所显示的阶段与计时基准。
  4. 注意:App Launch 模板会采集 time profile/thread-state trace;Time Profiler 可显示 App Life Cycle。不同模板的 Total 不能未经定义核对就拿来当 CoreProfile 的首帧 END。
  5. 私有归档建议:~/Perfowl-Local-Archive/build74-instruments-comparison-20260924/。原始 .trace 与原始 Session 不推送公共 Git、Webhook 或站点。脱敏摘要可放 artifacts/。

4. B 阶段:导出 Instruments 证据与区分观测层级 ​

先运行本机已验证的 xcrun xctrace version(已见 16.0)及实际导出命令:

bash
xcrun xctrace export --input "<OWNER_TRACE_PATH>" --toc --output "<PRIVATE_ARCHIVE>/run1-toc.xml"

根据真实 run1-toc.xml 的 table schema 选择 --xpath 导出相关 App Life Cycle、App Launch、Time Profiler、线程时间线;不要猜 schema,不要直接复制示例 schema 名冒充成功。导出失败就记录 exit code、stderr,改为 Instruments GUI 显示的详细时间线截图和 trace 元信息;不要因此要求 Owner 无条件重复测试。

建立分层表格:traceRunAlias | UI Total | first-frame/end name | app identity | source instrument | source timestamp type | exportable raw provenance | value quality | evidence path/hash。

区分:UI 显示某项耗时、trace 中导出某个阶段、导出原生 kdebug debugID、能够读到精确 DTX setConfig,这四种证据完全不同。.trace 能导出 App Life Cycle 并不自动证明能导出 Instruments 私有订阅原始 DTX 参数。若没有 wire config,就把 Apple 原生 bm/kdf2/tc 标成 UNKNOWN_NATIVE_CONFIG。

5. C 阶段:Perfowl 捕获链逐层取证 ​

  1. 核对原始 core-profile-chunks.bin 的 manifest SHA-256、29 chunk 的事件序列、kernel time 范围、host receive 时间;避免从 91 MB 原始数据打印无关个人信息。
  2. 检查解码器现有的 Initial Frame Rendering BEGIN/END debugID、对象归属、sceneWillEnterForeground() 未闭合事件、unmatchedBeginCount / unmatchedEndCount、unknownLifecycleFingerprints、lost marker 的发生窗口。
  3. 使用项目现有 offline replay 接口,先查 --help/对应测试用例获取真实 CLI 参数,不能编造 replay 命令。仅在独立输出目录重放,不覆写 Session。
  4. 特别核查 3 个超时后 chunk:是否含原始 endpoint、其 kernel timestamp 与 START 差是否合理、是否被 decoder 忽略、是否落入另一个 PID/thread/generation,以及重放结果是否仍旧缺失。raw 不存在不得通过变更解析器生成“修复后的 END”。
  5. 读取每轮 rawPayload.effectiveCoreProfileConfig 和配置签名,逐事件确认 filter 已下发;对照各轮的设备 lost marker 和 host queue drop,切勿把 host 0 dropped 等价于 device no loss。
  6. 建立 SOURCE CONFIG → DEVICE EMISSION → RAW CHUNK → HOST TRANSPORT → DECODER → TARGET ATTRIBUTION → TOTAL GATE 的断点证据矩阵。每一栏提供源文件、字段、SHA 和反证。

6. D 阶段:配置差分与因果归因 ​

按如下顺序判别:

  • 订阅覆盖差异:Apple 真机 trace 可证明某个生命周期事件来自 Perfowl 未订阅类别;若能证实,才提出最小增加单一过滤类别的受控方案。否则 NOT_PROVEN。现有 0x31CA0000 不可忽略。
  • 缓冲模式差异:存在 bm=0 对 bm=1 的可测试候选;先确认对应平台版本及行为文档/真实 trace evidence,再单独提出 A/B 实验,不与 filter/samplingTrigger 同时更改。
  • 录制时序差异:App 选择时预热只打开传输,开始采集后才真正激活 kdebug;对比 Instruments 是否确实“订阅已激活再启动目标 App”及两端 barrier 证据,不因仅看到 appReady 就假称已经录制。
  • 上游丢失:结合 device lost marker、ring 容量、chunk 到达速率、已缩减过滤类别的历史结果;参数更激进不一定更稳定。
  • 解码/归属问题:原始首帧 END 存在但未通过 debugID、thread/PID 或 phase state machine 时,给出针对性 fixture,优先离线修复证据;不能改写 raw。
  • 语义差异:Apple 的 Total 若不是 System Interface BEGIN → Initial Frame END,单独报告 NON_EQUIVALENT_ENDPOINT,而不是认定 Perfowl 订阅必然错误。

每条最终分类只能是 PROVEN_CONFIG_GAP、PROVEN_DECODER_GAP、PROVEN_DEVICE_LOSS、PROVEN_ENDPOINT_SEMANTIC_DIFFERENCE、INSUFFICIENT_EVIDENCE 或带精确限定的组合。区别已证实与合理怀疑。

7. E 阶段:仅在分析无法收敛时提交下一轮实验建议 ​

本批不修改现有已签名 Build 74,不重新打包,不自行启动新的 E4。若确需 A/B,只生成独立提案:

  • 设备 A / 系统版本留私有证据 / 同一个目标 App / 同一冷启动条件;
  • 优先每次仅改变 bm=0↔1 一项,或已被 trace 证实的某单个缺失类别一项;不同时更改 kdf2、bm、采样触发器;
  • 每轮记录设备端 lost marker、目标阶段完整率、完整且可配对的 START/END、原始体积、CoreProfile 提交延迟、Host/drop、Stop drain;
  • 只有明确得到 Owner/Lead 后续授权,才进入开发和真机采集。未经授权不得开启 kperf sampling trigger 或混合模型。

8. 交付 Lead AI 的固定格式 ​

私有归档内交付:

  • evidence-manifest.json、SHA256SUMS.txt,含来源、类型、时间、大小与哈希;
  • Instruments 每一轮的 trace-metadata.json、*-toc.xml、能合法导出的阶段明细与必要截图;
  • perfowl-actual-coreprofile-config.json,实际参数及签名、原始文件来源;
  • subscription-diff.csv,按字段展示 Perfowl actual | Instruments proven | Instruments unknown | discrepancy | evidence;
  • endpoint-timeline.csv,分别记录 kernel time / host receive time / UI milestone,禁止不同时间基直接做差;
  • raw-replay-findings.md,说明 29 chunk、3 个后到 chunk、首帧 END、device lost marker 的结果与限制;
  • final-audit.md,最重要的结论写在开头:缺失参数是否已证实、bm 是否值得 A/B、是否是 Apple 自己使用其他测量源、能否在不造假的条件下改进 Total,及建议下一动作。

交付态必须保持 judgement=pending-lead-ai;不得在此批宣布 Build74 E4 PASS、Hybrid C0 PASS、Total 可稳定率提升到某百分比。把以上路径、manifest SHA、核心证据和完整 final-audit 反馈给 Lead AI。若没有可访问的新 Instruments .trace,也要完成 Perfowl 本地基线与证据缺口清单,明确标为 TRACE_UNAVAILABLE/PARTIAL,不得拿旧 trace 冒充本轮结果。

Perfowl · Performance Observer