症状 → 最快解法

Xcode 27 为 xctrace record 提供了 2 种与记录选项相关的命令行入口:先查询模板可用选项,再传入修改后的 JSON 配置文件。 结论:可以把 Instruments 采集接入远程 Mac CI;先固定工作负载并查询当前模板选项,再生成、归档 trace。自动采集不等于性能门禁,是否回归要由受控重复测试和独立分析决定。依据:Apple 的 Xcode 27 发布说明及命令行工具参考。

谁该看:iOS/macOS 开发者,想为固定应用操作自动采集 Instruments trace、减少手动启动分析。 CI 工程师,需要保存并追踪远程 Mac 流水线中的性能记录。 研发平台维护者,正在判断哪些采集任务适合自动运行、哪些结论必须人工复核。

最后更新于 2026 年 10 月 30 日,核对依据为 Apple 的 Xcode 27 发布说明、命令行工具参考及 Instruments 文档;具体记录选项仍应以运行任务的 Xcode 环境查询结果为准。

第一步:先建立可比较的性能基线

先写清楚这次记录要回答什么问题。例如,是要分析某个页面操作的 CPU 活动,还是观察一个固定测试任务中的调用路径。确定对应的 Instruments 模板后,把执行步骤、输入数据和结束条件也记录下来;否则即使两次都生成了 trace,也可能记录的是不同工作负载。

把流水线拆成三个阶段,不要混成一个性能指标:

  • 构建:得到待测应用,记录代码提交与构建配置。
  • 运行工作负载:启动应用或测试,执行预先定义的输入和操作。
  • 采集 trace:在目标进程运行期间记录,再停止并留存结果。
每轮保持提交、测试数据、目标设备或模拟器、模板及执行条件一致。如果运行环境或工作负载变了,就把它标成新基线,而不是将差异直接归因于代码改动。Apple 的 Instruments 文档也将采集和后续比较作为不同环节;分析 CPU 时,可使用调用树或运行比较定位差异,但仍需确认比较的是同一操作区间。参考[Apple 的 Instruments 调用树与运行比较说明](https://developer.apple.com/documentation/xcode/analyzing-cpu-profiles-with-call-tree-views)。

第二步:在远程 Mac 上核实工具链

通过 SSH 登录远程 Mac 后,先确认实际使用的 Xcode,而不是只看机器上“装了命令行工具”。可按以下顺序检查:

xcode-select -p
xcodebuild -version
xcrun --find xctrace
xcode-select -p 显示活动开发目录;xcodebuild -version 用于核对构建工具版本;xcrun --find xctrace 则确认当前工具链能否定位到 xctrace。如果活动目录指向独立的 Command Line Tools 路径,或 xcrun 无法找到命令,先切换到目标 Xcode:
sudo xcode-select -s /Applications/<Xcode 名称>.app/Contents/Developer

如果流水线要在单个命令中选择另一个 Xcode,可按 Apple 的说明设置 DEVELOPER_DIR,避免悄悄依赖机器的全局默认值。Apple 明确指出,xctrace 随完整 Xcode 提供,不包含在单独安装的 Command Line Tools 包中;安装多个 Xcode 时,也要核对命令行工具的活动版本。参阅命令行工具安装说明及命令行工具设置说明。

⚠️ xcode-select -p 指向正确目录,不代表应用目标已经可访问。正式采集前,先验证项目能构建,并确认目标进程、模拟器或连接设备处于预期状态;否则故障可能发生在采集之前。

第三步:先查询模板选项,再准备配置

不要先复制一份来历不明的 JSON。Xcode 27 发布说明确认,可通过 --show-recording-options 查看指定模板或仪器的记录选项,并以 JSON 输出;调整后,再通过 --recording-options 传入配置文件。记录选项会受当前模板和工具链影响,因此查询结果才是这次任务的配置依据。

下面是命令结构示意,尖括号内容需替换为你的模板名称;它不是适用于所有模板、目标和项目的通用命令:

xcrun xctrace record \
  --template "<模板名称>" \
  --show-recording-options

将返回的 JSON 保存为配置文件后,只修改本次任务需要调整且已由查询结果确认的项,再通过相应参数传入:

xcrun xctrace record \
  --template "<模板名称>" \
  --recording-options "<配置文件路径>"

这就是接入 Instruments 记录选项的关键步骤:以目标模板当前提供的字段为准,不预设字段名,也不把某个模板的配置文件挪给另一个模板。Apple 的 Xcode 27 发布说明确认了查询和传入配置的能力;Apple 的自动化演示则展示了 xctrace 可用于程序化记录及指定记录目标,但具体行为仍要在你的 Xcode 版本和目标上验证。相关示例见 Apple 的 xctrace 自动化演示。

第四步:按固定工作负载生成 trace

将采集放在工作负载的前后边界明确的位置:应用先构建并启动,测试脚本执行固定输入,采集覆盖目标操作,工作负载完成后停止记录。不要在 CI 脚本里只启动 xctrace 就假定任务会自动按预期开始和结束;目标进程是否已启动、是否需要附加到已有进程,以及目标设备是否可用,都需要按项目实际情况确定。

示意结构如下,模板、目标、输出路径与运行脚本均为占位符:

set -o pipefail

# 构建与启动步骤:替换为项目自己的命令
./ci-start-target.sh

xcrun xctrace record \
  --template "<模板名称>" \
  --attach "<目标进程>" \
  --output "<产物目录>/<本次记录>.trace" \
  --time-limit "<经验证的时长>"

# 执行固定输入:替换为项目自己的测试脚本
./ci-run-workload.sh

这段仅用于说明流水线需要连接哪些步骤;实际命令参数、记录时长和工作负载编排应以当前 xctrace 帮助、模板要求及项目启动方式验证,不能照抄后就认定适配所有任务。Apple 的自动化演示展示了使用 xctrace record、模板、目标和输出文件进行记录的方式;它是命令结构的示例,不是对所有 CI 目标行为的保证。

脚本还要检查命令退出码、应用测试是否通过,以及目标路径下是否生成预期文件。任一步骤失败,都应让流水线留下可诊断的日志并按团队策略失败退出;否则“流水线绿灯”可能只代表脚本没有检查到真正的采集失败。

第五步:归档后验证 trace 可读

把 .trace 文件作为可追踪的流水线产物归档,并与以下信息一同保存:代码提交标识、Xcode 版本、运行目标、模板名称、工作负载标识和配置文件。记录这些元信息,才能在后续打开文件时判断它对应哪次代码与哪组测试条件。

归档不应止于“文件存在”。在独立复核步骤中,尝试用 Instruments 打开 trace,或按分析需要导出内容;确认数据能读取、目标操作覆盖在记录区间内,再把该产物标记为可分析。xctrace 的官方命令行参考列出记录、导入、导出和符号化等用途;Apple 的 Instruments 演示也提醒,trace 需要在工具中检查和解读。

提醒:trace 生成成功只证明采集步骤完成,不代表性能有所改善或已经发生回归。分析结论要结合相同工作负载下的基线;若 trace 含有敏感运行信息,还应在归档策略中限定访问权限和保留方式。

在流水线中部先回答这些问题

Xcode 27 怎么查询模板记录选项? 先确认活动开发目录和目标 Xcode,再对指定模板调用 xctrace record --show-recording-options。输出以当前环境提供的 JSON 为准;不要从其他模板复制字段后直接用于远程任务。

CI 生成的 trace 怎么保存才方便复核? 将输出指向流水线可收集的产物目录,检查命令退出状态与文件存在性,并一同保存提交、Xcode 版本、目标及工作负载标识。归档后打开或导出验证内容,而不是把文件名存在当作分析通过。

自动采集结果能直接做性能门禁吗? 不能。trace 是分析材料,不是自动判定性能变化的结论。门禁阈值需要来自项目自身的基线和重复测量;若执行条件变化或结果波动无法解释,就先保留记录供人工复核,不要让单次采集触发性能失败。

命令行工具不可用时,怎么确认活动开发目录? 先运行 xcode-select -p 查看当前路径,再按 Apple 文档通过 xcode-select -s 切换到目标 Xcode,或使用 DEVELOPER_DIR 为单次命令指定工具链。若安装的只是独立 Command Line Tools 包,xctrace 仍不可用;需要确认完整 Xcode 已安装。

第六步:试跑后再决定是否设门禁

先把采集任务放进隔离流水线,逐项验证构建、目标访问、工作负载、失败退出、trace 归档和后续分析。然后按条件选择运行策略:

  • 若相同提交、输入、目标和执行条件可以复现,且重复记录和分析流程都已验证,则纳入定期采集;性能门禁仍需另行制定指标与基线。
  • 若采集稳定,但结果解释依赖人工检查,则作为按需或变更触发的诊断产物,不将它设为自动门禁。
  • 若目标访问、输出归档或失败处理仍不可靠,则先留在隔离试跑,不进入常规流水线。
  • 若比较时工作负载或运行条件无法复核,则建立新基线,不把差异直接标记为回归。
下表是部署选择的流程评分,不是性能实测;高表示与该阶段目标匹配,不等于性能质量评分。 <
方案适合条件评分主要限制
隔离试跑工具链、目标访问或归档仍待验证优不应据此设性能门禁
定期采集并人工复核采集流程稳定,但团队尚未确认自动判定规则优需要安排分析与复核
自动性能门禁工作负载、重复测量、基线和阈值均已由团队验证可用条件变化时需重新评估基线
验收时,按流水线阶段核对交付,而不是只看任务是否变绿: <
阶段必须检查未通过时的处理
工具链活动目录、Xcode 版本、xctrace 可定位修正工具链后重跑
工作负载构建成功,目标与输入符合记录说明停止分析,先修复启动或测试
采集退出状态正常,目标路径存在预期 trace保留日志,定位采集失败
归档trace 与提交、版本、目标、模板和工作负载关联不标记为可复核产物
分析trace 可打开或导出,比较条件一致仅保留原始记录,不判回归
**远程 Mac 性能分析**的关键不是把命令塞进 CI,而是让每一份记录都能说明“用什么工具链、跑了什么操作、保存了什么证据”。如果你需要非本地 Mac 来执行 Instruments 采集,可先查看 [MACGPU 的远程 Mac 环境入口](https://macgpu.com/zh/index.html),再按真实目标验证访问方式和 trace 交付;确定需要持续使用 Apple Silicon 节点后,再对照 [MACGPU 的 Mac 方案页面](https://macgpu.com/zh/m4-dinggou.html)评估租期。相较于临时借用开发机,后者容易遇到环境被占用、工具链不一致和产物留存分散等问题;租赁远程 Mac 可提供独立的 macOS 执行环境,但若任务长期高负载且需要固定物理接口,自购设备可能更适合。