SuperAPI AI 工具集

ios-ettrace-performance

编程与开发

查看项目

更新于 10-15 11:27

技能介绍

用途

iOS ETTrace Performance 是一个用于从 iOS 模拟器应用中采集并解读 ETTrace 性能剖析(profile)的技能。适用于剖析启动或运行时延迟、对比多次 Trace、查找 CPU 占用较高的调用栈。当任务同时需要模拟器构建、安装、启动、UI 驱动、日志或截图时,可将其与 ../ios-debugger-agent/SKILL.md 配合使用。

核心理念与工作流

该技能强调聚焦式采集:选定一个聚焦流程,并写下预期的起止点。随后构建将被安装和剖析的那个确切的模拟器应用,将 ETTrace 临时链接进该应用目标用于模拟器/调试剖析,收集应用可执行文件与内嵌动态框架的 UUID 匹配 dSYM,采集一次启动或运行时 Trace,在运行后立即保留处理后的火焰图 JSON,并仅分析处理后的 JSON,报告流程、产物、热点和注意事项。应避免宽泛的“随便用一会儿应用”的采集方式,一次 Trace 应对应一个用户可见流程。

环境准备

每个剖析会话使用可写的运行目录。若 ETTrace 运行器 CLI 尚不可用,可通过 Homebrew 安装:brew install emergetools/homebrew-tap/ettrace。ettrace 是主机端 macOS 运行器;应用还必须为 iOS 模拟器架构链接 ETTrace.xcframework。该工作流已针对 ETTrace v1.1.0 处理后的 output_<thread>.json 文件(带顶层 nodes)验证。

将 ETTrace 链接进应用

需将 ETTrace 接入到正在被剖析的确切应用目标。集成应保持在明确临时的补丁中,除非用户明确要求保留,否则在剖析任务完成后移除。优先选项包括:复用仓库中已有的、兼容模拟器的 ETTrace.xcframework;若不存在,则从上游 ETTrace 包构建一个仅用于模拟器的副本到 RUN_DIR 中。应将框架直接链接进应用目标,而不仅是测试、资源、数据文件或嵌套启动器目标。确认启动日志打印 Starting ETTrace。由于模拟器模式监听固定的 localhost 端口,一次只能剖析一个已插桩 ETTrace 的模拟器应用。

当需要构建模拟器框架时,技能给出了使用 xcodebuild archive 与 xcodebuild -create-xcframework 的具体命令。对于 Bazel 应用,临时导入通常使用 apple_dynamic_xcframework_import 规则。对于 Xcode 项目,则临时将模拟器 ETTrace.xcframework 添加到被剖析的 debug 模拟器构建的应用目标的 Link Binary With Libraries / Embed Frameworks 阶段,剖析后再移除该接线。

符号化门槛

不应从未符号化的火焰图得出结论。每次采集前,须准备一个 dSYM 文件夹,包含应用 dSYM 以及任何内嵌的第一方动态框架 dSYM。应在生成已安装应用的最终构建之后收集 dSYM,技能提供了 collect_ios_dsyms.sh 脚本调用示例及相关参数(--app、--out-dir、--search-root、--extra-dsym 等)。对于必须符号化的应用自有动态框架,可添加 --require-framework <FrameworkName>;仅当所有内嵌框架均为应用自有或预期有符号时才使用 --require-all-frameworks。若报告可疑,可在 Trace 前用 dwarfdump --uuid 验证重要 UUID。ETTrace 退出后,读取其符号化摘要;将有意义的第一方“have library but no symbol”行视为 Trace 失败,除非其只是微小噪声。未符号化的系统框架或 ETTrace 内部桶通常可以接受。

采集

对于启动 Trace,技能给出了包含 CAPTURE_MARKER、清理旧 output JSON 及 ettrace --simulator --launch --verbose --dsyms "$DSYMS" 的命令序列。仅当测量启动或首屏渲染时使用 --launch。首次启动连接可能会强制退出应用,若被提示,应从模拟器主屏幕而非 Xcode 重新启动。对于安装后首次启动的 Trace,可临时在应用 Info.plist 中设置 ETTraceRunAtStartup=YES,然后运行 ettrace --simulator 并从主屏幕启动。

对于运行时流程 Trace,使用 ettrace --simulator --verbose --dsyms "$DSYMS"。从一个稳定屏幕开始,启动 ETTrace,只执行一个聚焦流程,等待可见工作完成,然后停止运行器。若需更广泛归因,可添加 --multi-thread;否则从主线程开始。在 Codex 中,应以 TTY 运行 ettrace 并用 write_stdin 回答问题;没有 TTY 时,运行器可能退出而没有有用的 Trace。

保留产物

下一次 ETTrace 运行可能覆盖处理后的火焰图文件,因此应立即保留新的 output_<thread-id>.json 文件。不要分析保存的 output.json;ETTrace 也以该名称提供查看器路由,而原始 emerge-output/output.json 文件不是本工作流期望的处理后火焰图产物。技能给出了保留脚本:创建带时间戳的 PRESERVED_DIR,检查 CAPTURE_MARKER,查找比标记新的 output_.json 并复制,同时用 analyze_flamegraph_json.py 生成 summary.txt。若找不到新的处理后 ETTrace 输出 JSON,则报错。应仅分析 RUN_DIR 中处理后的 output_.json 文件。若分析器拒绝该 JSON 形状,应使用 Homebrew ETTrace 运行器与匹配的应用侧 ETTrace.xcframework 标签重新采集,而非尝试解释被拒绝的文件。

解读 Profile

从 run-*/summary.txt 开始,必要时直接检查处理后的 JSON。报告内容应包括:确切流程、应用构建、模拟器型号/运行时与运行次数;处理后的火焰图 JSON 路径;最活跃的叶子节点与第一方 inclusive 调用栈及其采样权重或百分比;应用自有二进制的符号是否完整;以及注意事项,如首次运行设置、仅模拟器开销、网络波动或采样数偏低。仅当同一流程以可比设置采集时,才给出前后差异。

清理

剖析完成后移除临时的 ETTrace 应用接线,除非用户要求保留。根据当前任务决定保留或丢弃运行产物。