為 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
    
  • 符號套件使用的版本 ID (標記) 必須與它們參照的原始 CIPD 套件相同。如此一來,就可以一併匯總這些容器。

  • 如果多個包含去除的 ELF 二進位檔的 CIPD 套件一起滾動 (使用相同版本 ID),則可以在單一 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 套件。