Debug - Getting Traces (简体中文)
这篇文章目的在于帮助你创建一个调试用的Arch软件包,并且使用它来提供回溯和调试信息来将软件bug报告给开发者。
发现包的名称
一些调试信息的事实
当查看调试信息,如下:
[...] Backtrace was generated from '/usr/bin/epiphany' (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". (no debugging symbols found) [Thread debugging using libthread_db enabled] [New Thread -1241265952 (LWP 12630)] (no debugging symbols found) 0xb7f25410 in __kernel_vsyscall () #0 0xb7f25410 in __kernel_vsyscall () #1 0xb741b45b in ?? () from /lib/libpthread.so.0 [...]
你可以看到在出现??
的地方调试信息是缺失的,库的名称和执行的函数也是。相似的,当这一行(no debugging symbols found)
出现在调试信息中时,它意味着你不得不寻找指出的文件。
找到包
使用Pacman来获取包信息:
# pacman -Qo /lib/libthread_db.so.1 /lib/libthread_db.so.1 is owned by glibc 2.5-8
于是我们找到这个版本为2.5-8叫作glibc的包。通过重复这一步,我们能够创建一个我们不得不自己编译的软件包列表,来获取完整的堆栈回溯。
获取 PKGBUILD
为了从源码构建一个软件包,需要PKGBUILD包。通常你可以从以下位置获得PKGBUILD:
使用AUR
使用 AUR search page来找到相应的软件包。如果不在其中,这个包就在Arch Linux的官方镜像树中。如果(在aur中)找到了,点击它的名字并且下载Tarball
。使用 tar
命令来解压它并且更改目录
$ tar xvzf name_of_tarball.tar.gz $ cd name_of_tarball
使用ABS
如果这个包是官方树的一部分,安装ABS, 获取软件包的源码然后构建它:
$ ABSROOT=. abs core/glibc $ cd core/glibc $ makepkg -s
编译设置
这个阶段,如果你将使用makepkg
仅仅为了调试目的,你可以更改的它的全局配置文件。其它情况下,你应该仅仅更改每个你想要重新构建的软件包的PKGBUILD。
全局设定
至于pacman
4.1etc/makepkg.conf
已经在DEBUG_CFLAGS
和DEBUG_CXXFLAGS
有编译标志。为了使用它们,开启debug
makepkg选项并且禁用strip
。
更改makepkg
的配置文件~/.makepkg.conf
使之包含:
OPTIONS+=(debug !strip)
这些设定会强迫编译调试信息并禁用剥离(strip)可执行文件。(如果你不禁用strip
,调试信息也会生成,但是在单独的"foo"-debug
包中。)
仅单个软件包设定
更改foo
的PKGBUILD文件使之包含以下行:
options=(debug !strip)
在build()
函数内,在最开始添加以下行:
export CFLAGS="$CFLAGS -g -O1" export CXXFLAGS="$CXXFLAGS -g -O1"
Qt
除了之前的通用设置,还需要添加-developer-build
选项到PKGBUILD
的configure
脚本中。如果安装了 qtwebkit,编译 Qt 可能会出问题,所以需要先临时删除软件包qtwebkitAUR,使用下面的删除命令以忽略依赖检查:
# pacman -Rdd qtwebkit
编译完 Qt 后再重新安装 qtwebkit。
KDE应用
KDE 程序使用 cmake 进行编译,要编译进调试信息,请将-DCMAKE_BUILD_TYPE
修改为 Debug
。
构建和安装软件包
当在PKGBUILD的文件夹中使用makepkg
,这可能花费些时间:
# makepkg
然后安装这个软件包:
# pacman -U glibc-2.5-8-i686.pkg.tar.gz
获得回溯
真正的回溯 (或堆栈回溯)现在可以通过例如GNU调试器gdb来获得。 通过以下任一命令运行它:
# gdb /path/to/file
或:
# gdb (gdb) exec /path/to/file
路径是可选的,如果已经在$PATH
变量中设定过了。
然后在gdb
中,键入run
连同以下任何你想要程序运行时的参数,例如:
(gdb) run --no-daemon --verbose
开始执行这个文件。做任何必要的来激发这个bug。对于实际日志,键入以下行:
(gdb) set logging file trace.log (gdb) set logging on
然后:
(gdb) bt
然后输出回溯到在gdb
运行的目录中trace.log
。退出时,键入:
(gdb) set logging off (gdb) quit
# gdb /usr/bin/python (gdb) run <python application>
你也可以调试一个已经运行的程序,例如:
# gdb --pid=$(pidof firefox) (gdb) continue
总结
使用完整的堆栈回溯来告知开发者你之前发现的bug。他们会很感激,并且将帮助你改善你喜爱的程序。