初識 debuginfod

Posted by 每特17劃 on 2023-10-08

初識 debuginfod

讀到 fcamel 的一篇文章 fcamel 技術隨手記: 讀出 gcc/g++ 編譯的參數 ,文中揭示可利用 readelf 指令來抓取該 binary 的 gcc/g++ 編譯參數:

readelf --debug-dump f | grep DW_AT_producer

進一步想,手邊正在使用的 Arch Linux 系統, 是否也能用相同方法取得資訊?

就以往的經驗, Linux 系統上程式的 debug 資訊通常另外由 *-dbg*-dbgsym 的套件提供。例如 coreutils 套件會另外有 coreutils-dbgsym 的套件。

不過,目前主流的趨勢已改由新的 debuginfod 的機制來取代。

Arch Linux 也於 2022-02-02 上線了 debuginfod 的服務(註: Arch Linux - News: Debug packages and debuginfod)。資訊主頁爲:Debuginfod service - Arch Linux

Pasted image 20240428221656.png

另外,從其伺服器提供的報表: debuginfod - Dashboards - Grafana,也可一窺實際使用的流量。

而在 Arch Linux 上使用 debuginfod 的入口文件爲: Debuginfod - ArchWiki

試用

在 Arch Linux 上試用的方法如下:

Step 1. 先安裝 debuginfod 的套件

指令如下:

pacman -S debuginfod

其中 libelf 作爲 debuginfod 的 dependency 也會一併安裝進來。 安裝後,預計會有下述的執行檔跟設定檔:

  • /usr/bin/debuginfod-find
  • /etc/profile.d/debuginfod.sh
  • /etc/debuginfod/archlinux.urls

Step 2. 設定 $DEBUGINFOD_URLS 的環境參數

手動設定環境的指令如下:

export DEBUGINFOD_URLS="https://debuginfod.archlinux.org"

但不必每次都手動執行,若重啓系統(重新登入、重開機)的話,系統會自動讀入 /etc/profile.d/debuginfod.sh/etc/debuginfod/archlinux.urls 的設定,而自動初始化 $DEBUGINFOD_URLS 的環境參數。

Step 3. 測試 debuginfod-find 工具

執行測試指令如下:

debuginfod-find debuginfo `which ls`

若成功的話,預期會有如下的結果:

$ debuginfod-find debuginfo `which ls`
/home/users/.cache/debuginfod_client/7aa8f52223e371fb77314d9a363129574096093b/debuginfo

Step 4. 測試 readelf 抓取資訊

readelf --debug-dump `which ls` | grep -e "DW_AT_producer\s*:" | head -1

若成功的話,預期會得到結果如下:

$ readelf --debug-dump `which ls` | grep -e "DW_AT_producer\s*:" | head -1
    <d>   DW_AT_producer    : (indirect string, offset: 0x8f): GNU GIMPLE 13.2.1 20230801 -march=x86-64 -mtune=generic -g -g -O2 -O2 -fno-openmp -fno-openacc -fPIC -fcf-protection=full -fno-plt -fexceptions -fstack-clash-protection -fcf-protection=full -fltrans

如此,就也能得到上述 fcamel 方法的結果。

Step 5. 測試 gdb

執行指令:

gdb `which ls`

在遇到提示問題時,回答 y,如下:

Enable debuginfod for this session? (y or [n]) y

之後就照往常的方式使用。預期過程如下:

$ gdb `which ls`
GNU gdb (GDB) 14.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/ls...

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Reading symbols from /home/users/.cache/debuginfod_client/7aa8f52223e371fb77314d9a363129574096093b/debuginfo...                                                
(gdb) break main
Breakpoint 1 at 0x3050: file src/ls.c, line 1655.                                                                                                            
(gdb) run
Starting program: /usr/bin/ls 
[Thread debugging using libthread_db enabled]                                                                                                                
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7fffffffe868) at src/ls.c:1655
1655	{
(gdb) 

遇過的問題

分享一些遇到的問題跟檢查的方法如下:

Check 1. 確認環境參數,且網站連線正常

echo $DEBUGINFOD_URLS
curl -vL $DEBUGINFOD_URLS

Check 2. 不是所有的套件都有 debug info

有提供 debug info 的,大多是 C/C++ based 的程式。而像是 d-feet 這類由 python 寫的程式,是沒有 debug info 的。

可查詢線上的套件清單資訊,看是否有包含:

查所在的套件可參考下述指令:

pacman -F /usr/bin/ls
pacman -Ql | grep -e "\s/usr/bin/ls$"

Check 3. 確認版本一致

要注意到,本地端的版本和遠端是否一致。例如,以上述 /usr/bin/ls 所在的 coreutils 套件爲例。若本機端的版本是 coreutils-9.4-3 而 Arch Linux 伺服器上的版本是 coreutils-9.5-1 ,那就會取不到 debug info 的資料。

關於 debuginfod

debuginfod 是 elfutils 的一部分。就目前溯源的部分,最早的紀錄是 2019-10-28 的 sourceware.org Git - elfutils.git/commit ,主要作者爲 Aaron Merey 、 Frank Ch. Eigler。

在其專案主頁,也列有早期的文件,例如:

Ref.

2023-10-09

參考 Setup Glibc Debug Symbols on Arch Linux | Ice1187’s Blog 一文。 提到在 ~/.gdbinit 的設定檔可設定 set debuginfod enabled ask

更詳細的設定方式可參考上游文件: Debuginfod Settings (Debugging with GDB)

參考指令:

show debuginfod enabled
show debuginfod urls
show debuginfod verbose

其中 enabledon, off, ask 三個選項。