符号软件包用于日志中的符号化和调试崩溃。包含 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 软件包。