为 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 哈希值派生的十六进制字符串。每个此类文件都应与原始软件包中具有相同 build-id 的剥离 ELF 二进制文件匹配。

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

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

  • 如果多个 CIPD 软件包中包含已剥离的 ELF 二进制文件(使用相同的版本标识符),可以将所有这些软件包的调试符号分组到一个 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) 传递给链接器。

只需调用 llvm-objcopy 一次,即可生成剥离后的二进制文件和相应的 build-id 目录,如以下示例所示:

# Copy out/libfoo.so to symbols/<xx>/<xxxxxxx>.debug according to its
# `build-id` value (requires the library to be linked with -Wl,--build-id when
# using Clang), and also copy the stripped version of the library to
# stripped/libfoo.so
#
# NOTE: To strip executables, instead of libraries, replace --strip-all below
#       with --strip-sections
#
UNSTRIPPED_LIB=out/libfoo.so
STRIPPED_LIB=stripped/libfoo.so
SYMBOLS_DIR=./symbols

llvm-objcopy --strip-all \
    --build-id-link-dir="${SYMBOLS_DIR}" \
    --build-id-link-input=.debug \
    "${UNSTRIPPED_LIB}" "${STRIPPED_LIB}"

根据需要重复多次以填充 symbols/ 目录,然后上传其中的内容(symbols/ 下的文件)作为您的符号软件包。

不要忘记将 stripped/ 目录的内容也复制到预构建的 CIPD 软件包。