软件的bug通常是不可避免的,开发者通常使用gdb,systemtap这些使用工具加载debuginfo来定位问题。
一般源代码是人类可读的,机器不可读,而二进制文件是机器可读,人类不可读的。当程序遇到问题时,机器只知道运行的指令是什么,人类一般无法通过二进制指令来快速定位问题。此时就需要将此处的指令和源代码关联起来,当运行的指令出现bug时,可以快速的关联到源代码的位置上。debuginfo就是起到这个作用,是二进制指令到源代码的一个桥梁。调试信息一般就是变量名,变量类型,函数名,函数参数,函数的地址范围,行号和地址的对应关系等等,这些内容按照一定的格式写入到编译的文件中。现在最常用的格式是 DWARF(Debugging With Attributed Record Formats) 。有关DWAERF
(https://dwarfstd.org)的介绍请见(https://dwarfstd.org/doc/Debugging using DWARF-2012.pdf)。
debuginfod 是一个用于传输调试信息资源的http文件服务器。
debuginfod会定期扫描指定路径下的内容,比如deb和rpm打包文件等。从中提取基于Build-id
的调试信息和可执行文件,并使用sqlite
来保存这些信息。
当用户使用客户端工具访问已知的Build-id
的调试信息时,debuginfod就会返回对应的资源。支持获取debuginfo
,executable
和source file
。
文件的Build-id
可以使用readelf
命令来获取,比如获取dde-dock=5.5.66-1
的Build-id
。
❯ readelf -n /usr/bin/dde-dock | grep Build.ID
Build ID: 3f958ed5f3924da2e3ba2e07a9e065ecbba59437
debuginfod支持扫描deb,rpm和ELF/DWARF文件格式。下面是一些简单搭建使用的参数,更多参数请参考debuinfod的man手册。
-U path/to/debs/ # 扫描的deb文件路径。
-R path/to/rpms/ # 扫描的rpm文件路径。
-I REGEX --include=REGEX -X REGEX --exclude=REGEX # 扫描过程中排除和包含文件的正则规则。
-p port # 启动的端口。
-L # 是否处理symlink,当目录中包含软连接时,需要开启这个参数。
在deepin上,使用下面命令快速启动一个debuginfod
服务器。默认端口为8002
sudo apt insatll debuginfod
debuginfod -U path/to/debs/
可以通过编写service文件使用systemd 来对debuginfod的服务做管理。
[Unit]
Description=Debuginfod Service
Documentation=man: debuginfod(8)
After=network.target nginx.service
[Service]
EnvironmentFile=/etc/sysconfig/debuginfod
ExecStart=/usr/bin/debuginfod --port=${PORT} --database=${DATABASE_FILE} -U ${REPO_PATH}
[Install]
wantedBy=multi-user.target
配置DEBUGINFOD_URLS
环境变量指向上游的debuginfod服务器,比如在deepin上使用deepin提供的debuginfod服务器。如果长期使用,可配置到.bashrc
文件中。
export DEBUGINFOD_URLS=https://debuginfod.deepin.com
然后使用对debuginfod支持的客户端来获取调试信息。比如debuginfod-find
,gdb
,systemtap
,perf
等。
deepin 20通过gdb加载debuginfod的调试信息:
sudo apt install gdb
export DEBUGINFOD_URLS=https://debuginfod.deepin.com
gdb /usr/bin/gdb
# 出现下面提示即从debuginfod服务器下载并加载调试信息
Reading symbols from /usr/bin/dde-dock...
Downloading separate debug info for /usr/bin/dde-dock...
Reading symbols from /home/tsic/.cache/debuginfod_client/3f958ed5f3924da2e3ba2e07a9e065ecbba59437/debuginfo...
.......
Starting program: /usr/bin/dde-dock
.......
Downloading separate debug info for /lib/x86_64-linux-gnu/libdtkwidget.so.5...
.......
Downloading separate debug info for /lib/x86_64-linux-gnu/libsystemd.so.0...
debuginfod对deb打包方式获取源码的支持有限,请见can't download source code
各个client对debuginfod的支持情况(2022.08)以下数据来自debuginfod
tool | status |
---|---|
elfutils | released in version 0.178, 2019-11 |
systemtap | automatic via elfutils |
dwarves | automatic via elfutils |
dwgrep | automatic via elfutils |
ltrace | automatic via elfutils |
libabigail | automatic via elfutils |
binutils | released in version 2.34, 2020-02 |
gdb | released in version 10.1, 2020-10 |
dyninst | released in version 11.0 2021-04 |
valgrind | released in version 3.17.0, 2021-03 |
annocheck | released in version 9.03, 2020-01 |
delve | released in version 1.7.2, 2021-09 |
llvm | symbolizer merged, server merged, lldb help wanted, see also |
bpftrace | released in version 0.21.0, 2021-07 |
perf | released in linux 5.10, 2021-01 |
systemd-coredumpd | help wanted |
retrace/abrt/faf | in progress [email protected] |
vtune | help wanted |
pixie | help wanted |
sentry symbolicator | partly released partly help wanted |
VS Code | partly automatic via gdb |
WinDbg | released in version 1.2104.13002.0, 2021-04 |
UDB | released in version 6.5 |