用途:把 Google Play Console(崩溃或 ANR 面板)导出的混淆堆栈还原为符号化堆栈,为每个原生与 Flutter 帧给出文件与行号,便于定位问题。
适用前提(三者需同时满足):应用为面向 Android 的 Flutter 应用;堆栈来自 Google Play Console 导出(含 pc 0x… 帧,可能带 # Application: / # Version: 头);release 构建由 Codemagic CI/CD 产出,且工作流上传了 android_native_debug_symbols.zip 与 <AppName>_<N>_artifacts.zip(Flutter split-debug-info 的 .symbols 文件)。若构建启用了 R8/ProGuard,还会拉取 mapping.txt,用于把 Ka.n.l+8 这类 Java 帧还原为可读类名方法名。
环境要求:Codemagic API Key(通过 CODEMAGIC_API_KEY 环境变量或仓库根目录 .codemagic-api-key 文件提供);带 llvm-addr2line 的 Android NDK(默认 ~/Library/Android/sdk/ndk/27.3.13750724,可用 ANDROID_NDK_HOME 覆盖);unzip、python3 3.10+、bash。
主要脚本:scripts/codemagic_fetch_artifacts.py(发现并下载符号产物,JSON 输出到 stdout);scripts/symbolize_flutter_anr.sh(顺序无关地识别并符号化堆栈);scripts/deobfuscate_r8.py(批量解析 R8/ProGuard 映射,通常由 bash 脚本调用)。
使用方式:先把堆栈保存为文件(如 /tmp/play-stacktrace.log),从堆栈中识别包名与版本;再运行 python3 scripts/codemagic_fetch_artifacts.py 列出应用,用 --app 指定显示名、--build 指定版本下载符号;最后执行 bash scripts/symbolize_flutter_anr.sh <trace> <native zip> <flutter zip> [mapping.txt],参数顺序不限,默认输出 <trace>.symbolized.txt,可用 -o 覆盖,--json 输出机器可读摘要。
限制:Build ID 必须与崩溃构建完全一致,版本不匹配会导致所有帧 [UNRESOLVED];版本字符串需与 Codemagic 的 version 字段精确匹配(可容忍 v 前缀,但不能附加构建号);libflutter.so 为 stripped,即使 Build ID 匹配也无调试信息;系统库帧(libc.so、libart.so、boot.oat 等)标记为 [SYSTEM] 属正常;非 Codemagic 构建在下载步骤会失败。