为 ELF 二进制文件发布 CIPD 符号软件包

符号软件包用于在日志中进行符号化和调试崩溃问题。包含 Fuchsia ELF 二进制文件的 CIPD 预构建软件包需要有一个配套符号软件包,其中包含二进制文件的调试信息。

符号软件包的要求

  • 原始 CIPD 软件包中的每个 ELF 二进制文件都必须包含一个 ELF NT_GNU_BUILD_ID 备注部分,其中包含一个唯一的 build-id 哈希值,用于唯一标识其与调试无关的内容。

    此注释是在生成 ELF 二进制文件的链接时创建的。较新版本的 GCC 或预构建的 Fuchsia Clang 工具链会自动生成它。不过,常规 Clang 需要传递特殊的链接器标志(即 -Wl,--build-id)。

  • 符号软件包必须使用典型的 .build-id 目录布局,用于在单独的文件中存储调试信息

    这意味着,每个文件都必须存储为 <xx>/<xxxxxxxxxx>.debug,其中 <xx><xxxxxxxxx> 是从未剥离二进制文件的 build-id 哈希值派生的十六进制字符串。每个 .debug 文件都应是未剥离的 ELF 二进制文件本身的副本,而不仅仅是提取的调试信息。这些文件应映射到与原始软件包中的 build-id 相同的剥离 ELF 二进制文件。

    以下示例展示了包含未剥离 ELF 二进制文件的 CIPD 符号软件包的目录结构:

    1d/
      bca0bd1be33e19.debug
    1f/
      512abdcbe453ee.debug
      90dd45623deab1.debug
    2b/
      0e519bcf3942dd.debug
    3d/
      aca0b11beff127.debug
    5b/
      66bc85af2da641697328996cbc04d62b84fc58.debug
    
  • 符号软件包必须使用与其所引用的原始 CIPD 软件包相同的版本标识符(标记)。这样一来,它们就可以一起发布。

  • 如果将多个包含剥离的 ELF 二进制文件的 CIPD 软件包打包在一起(使用相同的版本标识符),则可以将所有这些软件包的调试符号组合到单个 CIPD 符号软件包中,但这并非必需。

  • 符号软件包的 CIPD 路径需要使用以下后缀:

    -debug-symbols-<ARCH>
    

    例如,myproject/fuchsia/mypackage-debug-symbols-amd64 包含 myproject/fuchsia/mypackage-amd64 预构建软件包的符号。

  • 所有符号软件包的 Jiri 签出路径都必须为 ${FUCHSIA_DIR}/prebuilt/.build-id

生成符号软件包

如需生成符号包,您需要:

  • 使用 DWARF 调试信息编译所有 ELF 二进制文件(例如,将 -g 标志传递给编译器,即使在发布模式下也是如此)。

  • 为 ELF 二进制文件生成 NT_GNU_BUILD_ID 备注。

    这是近期 GCC 版本和 Fuchsia 预构建 Clang 工具链的默认设置,但常规 Clang 需要向链接器传递特殊标志 (-Wl,--build-id)。

生成符号软件包的推荐方法是使用 buildidtool 预构建工具:

  • 对于非树型 build,您可以从 CIPD 获取此工具。

使用 buildidtool 生成符号软件包目录结构:

# Example assuming your unstripped binary is at out/libfoo.so and you want to
# create the symbols directory at ./symbols

UNSTRIPPED_BINARY=out/libfoo.so
SYMBOLS_DIR=./symbols
BUILDIDTOOL="${FUCHSIA_DIR}/prebuilt/tools/buildidtool/linux-x64/buildidtool" # Adjust path as needed

mkdir -p "${SYMBOLS_DIR}" # Ensure symbols directory exists

"${BUILDIDTOOL}" --build-id-dir="${SYMBOLS_DIR}" -entry .debug="${UNSTRIPPED_BINARY}" -stamp "$(mktemp)"

对预构建软件包中的每个未剥离的 ELF 二进制文件重复此 buildidtool 命令,以填充 symbols/ 目录。

然后,将 symbols/ 目录的内容(而非目录本身)作为符号软件包上传到 CIPD。

在本地测试符号软件包

在本地测试符号软件包之前,您应了解符号软件包的 jiri 条目是什么样的:

<package name=$CIPD_PATH-debug-symbols-$cpu # Example: ~/fuchsia/mypackage-debug-symbols-amd64
         path="prebuilt/.build-id"
         version=$CIPD_VERSION
         attributes="debug-symbols,debug-symbols-$cpu,debug-symbols-$project"/>

属性说明

  • path="prebuilt/.build-id":所有符号软件包都必须下载到项目检出的 ${FUCHSIA_DIR}/prebuilt/.build-id 目录中。
  • attributes="debug-symbols,debug-symbols-$cpu, debug-symbols-$project":此属性用于控制何时下载符号软件包。
    • debug-symbols-$cpu(例如,debug-symbols-arm64debug-symbols-amd64)。
    • debug-symbols-$project:此属性用于下载与您的特定项目相关的符号软件包。如需在本地进行测试,请参阅以下说明。
    • debug-symbols:常规惯例。

如需使用 jiri 提取符号软件包以进行本地测试,您需要配置 jiri。例如,如需将 jiri 配置为提取 debug-symbols-$project,请执行以下操作:

jiri init -fetch-optional=debug-symbols-$project

然后,检索软件包:

jiri fetch-packages --local-manifest

请注意,通过 Jiri 属性选择启用符号软件包下载功能可能会大幅增加项目检出所用的磁盘空间。您可以手动修改结账系统顶层目录中的 .jiri_root/attributes.json 文件,以移除已选择启用的属性。