10

我目前的问题是 libwebkitgtk-3.0-0,但我想这个问题足够通用。

我的应用程序在 webkit 代码的某处崩溃。我的假设是我们正在做一些愚蠢的事情,并想知道是什么。最简单的事情是设置断点或使用库的调试版本。

  1. 如何获得构建哪个库的确切源代码?我在转储核心后得到堆栈跟踪,但行号 gdb 说与我在代码中看到的不匹配。换句话说,如果我安装 libwebkitgtk-3.0-0 我想获得它的确切源代码。

  2. 我已经安装了 webkit 库的调试版本。这些调试版本是否具有与使用 --enable-debug 标志编译 webkit 相同的功能?调试版本的 webkit 启用基于 WEBKIT_DEBUG 环境变量的日志记录,但即使使用调试版本的库,我也无法获得相同的日志记录。

  3. 如何使用我设法编译的调试版本?我设法在我的机器上编译 webkit 并尝试摆弄加载路径等。无论我做什么,我的应用程序都不会获取新的共享库 - 我可以根据用户代理签名来判断。有一次,我设法拿起图书馆,但随后 SSL 停止工作。GtkLauncher 确实会发生同样的 SSL 问题。所以我在某个地方犯了错误。

感谢您的指点。

4

4 回答 4

29

TL;DR:安装libwebkitgtk-3.0-0-dbg安装 libwebkitgtk-3.0-0-dbg,然后你就有了必要的调试符号。

##对于调试符号,您通常不必从源代码安装。

如您所知,要为您自己构建的软件获取调试符号,您可以使用-g.

对于通过操作系统的包管理器安装的软件(包括libwebkitgtk-3.0-0, 这里),至少对于官方包,通常还有提供调试符号的包。

您实际上不需要对程序或库进行调试构建即可在gdb. gdb还支持在/usr/lib/debug.

根据您问题上的标签,您使用 Ubuntu。在 Ubuntu 上,调试符号包有两种可用:-dbg-dbgsym. 位于 的程序或库在获取调试符号。/path/usr/lib/debug/path

##-dbg

这些包的命名通常与提供实际可执行文件或库文件的相应包不同。它们的命名通常类似于-dev包(提供头文件)和-doc包。一个-dbg包的名称中的库版本编号有时比实际的库包少,有时涵盖多个其他包中提供的二进制文件。

例如,libgtkmm-3.0-1的对应-dbg包是libgtkmm-3.0-dbg

另一方面,有时-dbg包的名称与它提供符号的包相同(-dbg后缀除外)。例如,libwebkitgtk-3.0-0的对应-dbg包是libwebkitgtk-3.0-0-dbg 那就是你想要的那个。

您可以在软件中心安装它或通过运行:

sudo apt-get update && sudo apt-get install libwebkitgtk-3.0-0-dbg

现在,当您调试链接到由 提供的库的程序时libwebkitgtk-3.0-0gdb将自动从 提供的文件中加载符号libwebkitgtk-3.0-0-dbg

##-dbgsym

有时官方包提供的二进制可执行文件没有任何-dbg包中提供的符号。发生这种情况时,通常您可以安装该-dbgsym软件包。

-dbg包不同,-dbgsym包:

  • 几乎总是简单地(并且可以预见地)命名提供程序或库本身的包X-dbgsym在哪里。X
  • 由特殊的软件源(存储库)提供,提供相应程序/库包和-dbg包的软件源不同。

由于-dbgsym包位于单独的存储库中,因此您必须启用这些存储库。他们的 DEB 线路是:

deb http://ddebs.ubuntu.com YOUR_RELEASE main restricted universe multiverse
deb http://ddebs.ubuntu.com YOUR_RELEASE-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com YOUR_RELEASE-security main restricted universe multiverse
deb http://ddebs.ubuntu.com YOUR_RELEASE-proposed main restricted universe multiverse

要启用它们,您可以运行以下命令(改编自DebuggingProgramCrash“Ubuntu 文档 wiki 贡献者”第 2 节):

echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-security main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse
" | sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01
sudo apt-get update

如果您使用的是开发版本(alpha 或 beta),请忽略斜体行。但是,如果您在稳定后继续使用该版本,请确保添加它们。

这些命令做了三件事:

  1. 创建文件/etc/apt/sources.list.d/ddebs.list(其中包含 DEB 行)。
  2. 导入这些存储库的签名密钥。
  3. 更新您的系统信息,了解哪些软件包和版本可用于从何处安装。

因此,如果您想使用-dbgsym-provided 符号而不是-dbg提供的符号,则-dbgsymlibwebkitgtk-3.0-0是(根据上面的简单命名约定)libwebkitgtk-3.0-0-dbgsym

您可以在同一系统上同时安装-dbg和包,但如果它们为任何相同的文件提供符号,则不能。所以又互相冲突;它们不能同时安装。-dbgsymlibwebkitgtk-3.0-0-dbglibwebkitgtk-3.0-0-dbgsym

##使用符号

在大多数类 Unix 操作系统上,调试器会自动查找已安装的符号。Ubuntu 也不例外——在 Ubuntu 中,会gdb自动在/usr/lib/debug. 所以你不需要做任何特别的事情。

但是,如果您确实需要告诉gdb加载特定的调试符号文件,您将使用该标志。有关详细信息,请参阅GNU 手册gdb(1)-s file

于 2013-01-20T02:14:18.900 回答
4

1)当我需要挖掘通过包安装的库时,我要做的第一件事就是从源代码安装它。我的意思是配置/制作/制作安装。我通常将源代码放在 /usr/local/src 中并将其安装在 /usr/local 中。在我看来,这是运行您拥有源代码的确切代码的最可靠方法。

3)

如何使用我设法编译的调试版本?

这听起来像你做了我上面描述的事情。您需要做的是确保您的软件正在使用包含和链接目录,这些目录托管您的已编译、启用调试的库。这意味着确保设置了 -I/usr/local/include 和 -L /usr/local/lib 标志,并且它们位于 /usr/include 和 /usr/lib 之前。

通过从 ubuntu 安装中删除库的二进制版本,您可以更加确定,确保您构建和安装的版本是硬盘上唯一存在的版本。通过这种方式,您将确定您能够配置您的应用程序以使用该库。否则它只会失败,而不是你不断地想知道它是使用新库还是旧库。

2) 通常是的。但这取决于库是如何编写的,以及 ubuntu 打包器决定做什么。

使用本地构建的库编译程序后,请先查看是否遇到相同的错误。如果不是,那么这也是一个数据点。自从上次 ubuntu 打包库以来,问题可能已经解决了。也许库没有正确打包,这就是问题所在。您甚至可能会遇到新的错误,因为 ubuntu 打包程序以某种方式配置了库,以便它可以工作,而您没有做同样的事情。无论如何,你都会得到有趣的线索。

祝你好运

于 2013-01-15T19:43:05.990 回答
3

@Eliah 的回答告诉了如何以方便的方式获取符号。

问题仍然存在,“我如何获得确切的源代码?” .

我通常这样做apt-get source <pkgname>很好,除非我必须手动告诉 gdbdir <path-to-wherever-I-put-the-source>和 woe betide 如果它是像eglibc这样的包,必须弄清楚路径引用来自nss子目录,而不是根目录。

在 RHEL 上,例如yum install --enable-repo rhel-debuginfo libX11-debuginfo(仅yum install libX11-debuginfo在 CentOS 7 上),您可以立即在 gdb 中获得完整的符号和源代码,而无需额外的混乱。我仍在寻找 Ubuntu 上的便利。

于 2013-05-09T15:50:50.463 回答
0

为了针对动态库进行调试,您可以按照建议添加带有符号和源发行包的 dgb 齿轮。然后需要检查调试符号表的编译目录是否与安装源的路径匹配,如果不匹配,则应在gdb中映射路径。按照命令启用 glibc 的调试

$ objdump -g /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.27.so | sed -n '/<.*>\s\+DW_AT_comp_dir/ {s/\s\+<.*>\s\+//; p;}' | sort | uniq
DW_AT_comp_dir : (indirect string, offset: 0x1127a): /build/glibc-OTsEL5/glibc-2.27/malloc
...
DW_AT_comp_dir : (indirect string, offset: 0xd139): /build/glibc-OTsEL5/glibc-2.27/stdio-common
DW_AT_comp_dir : (indirect string, offset: 0xef40): /build/glibc-OTsEL5/glibc-2.27/libio
$ ls -ld glibc-2.27/{stdio-common,libio}
drwxrwxr-x 3 fusillator fusillator 12288 feb 1 2018 glibc-2.27/libio
drwxrwxr-x 3 fusillator fusillator 4096 feb 1 2018 glibc-2.27/stdio-common
$ gdb ./hello
Reading symbols from ./hello...done.
(gdb) set substitute-path /build/glibc-OTsEL5/glibc-2.27 glibc-2.27
(gdb) b main
Breakpoint 1 at 0x63e: file hello.c, line 10.
(gdb) run
Starting program: hello
Breakpoint 1, main () at hello.c:10
10 printf("hello world\n");
(gdb) s
_IO_puts (str=0x5555555546e4 "hello world") at ioputs.c:33
33 {
(gdb) backtrace
#0 _IO_puts (str=0x5555555546e4 "hello world") at ioputs.c:33
#1 0x000055555555464a in main () at hello.c:10
于 2018-12-09T11:53:15.343 回答