缺少单独的调试信息

缺少单独的调试信息

我正在尝试在 Fedora 机器中使用 GDB 调试代码。每次我运行它时它都会生成此消息。

Missing separate debuginfos, use: debuginfo-install glibc-2.18-12.fc20.x86_64 libgcc-4.8.3-1.fc20.x86_64 libstdc++-4.8.3-1.fc20.x86_64

我的问题:

  1. 这些包应该默认在 GDB 中吗?
  2. 每个包的功能是什么?
  3. 在实际生产环境中应该为GDB安装这些包吗?
  4. 如果我不安装这些软件包可以吗?会有什么效果呢?

答案1

  1. No.gdb由一个维护者打包,glibc由另一个维护者打包,等等,所有这些都由不同的维护者打包gcclibstdc将这些调试信息打包起来gdb需要大量的协调。每当其中一个包发生变化时,维护者gdb就必须重新打包并发布。管理起来会变得相当麻烦。gdb还可以调试其他语言,例如java,不需要列出的库的调试信息。

  2. 这些debuginfo包包含从可执行文件中剥离的源代码和符号。它们仅在调试期间需要,因此在正常使用期间是多余的。它们确实占用了相当多的空间,因此在生产版本期间被剥离。

  3. 这取决于。大多数 C 代码都会使用glibcetc。但是,如果您正在调试包 X 并且不需要深入研究其内部,glibc您可以在不安装它的情况下进行管理。如果您想一直跟踪代码gdb到底层glibc,或者您认为库本身存在错误,那么您需要安装它。另一方面,某些 C 代码可能是静态链接的,并且应该在其自己的 debuginfo 包中包含所需的所有内容,或者可以用另一种语言编写应用程序。两者都不需要安装这些。

  4. 是的。不安装这些软件包的后果是您将无法有效地调试它们提供的例程。如上面的 3 所示,这完全取决于您是否需要在该级别进行调试。

笔记:您会发现许多应用程序已经过优化(使用-O编译器中的标志),但使用 debuginfo 的调试效果不佳。解决方法是重新编译而不进行任何优化。

答案2

我的解决方案可能对那些收到此警告的人有所帮助。

  1. 它们在fedora中被打包成不同的包。该命令dnf install debuginfo-install packagename可以解决这个警告。

我的操作系统是 fedora 29 工作站 x86_64。调试信息包可以在以下位置找到存档仓库, 例如glibc-debuginfo-2.28-9.fc29.x86_64.rpm,glibc-debuginfo-common-2.28-9.fc29.x86_64.rpm,libgcc-debuginfo-8.2.1-2.fc29.x86_64.rpm,libstdc++-debuginfo-8.2.1-2.fc29.x86_64.rpm

其他版本的包就在这里勾选即可,存档版本或者最新版本

源代码:gcc-mirror 在 github 上在线,glibc 在线源软件,gcc 在线源代码中的 libstdc++. 源码包包括 gcc, gdb, glibchttps://ftp.gnu.org/gnu/

  1. 为什么 gdb 显示消息“缺少单独的调试信息”?

要调试任何应用程序,需要在系统上安装源代码和调试符号,以获得有关系统中各个帧的更多信息。

因此,需要安装尝试调试的二进制文件的所有依赖项的 debuginfo 包。

debuginfo包包括.debug文件和源文件。安装这些软件包后,.debug文件将存储在fedora 29 中/usr/lib/debug/lib64/,源文件将存储在其中。/usr/src/debug/并且链接.gnu_debuglink部分将添加到 glibc 库文件中。

例如,/usr/lib/debug/lib64/libc-2.28.so.debug从安装glibc-debuginfo-2.28-39.fc29.x86_64

[user@localhost myctest]$ rpm --query --list glibc-debuginfo-2.28-39.fc29.x86_64 | grep libc-2.28.so.debug
/usr/lib/debug/lib64/libc-2.28.so.debug
[user@localhost myctest]$ readelf -S /usr/lib64/libc-2.28.so | grep debug
  [73] .gnu_debuglink    PROGBITS         0000000000000000  002a6df0
[user@localhost myctest]$ readelf -S /lib64/libc-2.28.so | grep debug
  [73] .gnu_debuglink    PROGBITS         0000000000000000  002a6df0
[user@localhost myctest]$ readelf --debug-dump=links /usr/lib64/libc-2.28.so 
Contents of the .gnu_debuglink section:

  Separate debug info file: libc-2.28.so.debug
  CRC value: 0x9bd5ece3

和源文件:

[user@localhost myctest]$ ls -l /usr/src/debug/
total 4
drwxr-xr-x. 60 root root 4096 Aug 10 18:36 glibc-2.28-110-g57922433fa

生成这些包的脚本是 /usr/lib/rpm/find-debuginfo.sh

您可以手动制作自己的.debug文件。

尝试一个例子:

#include <stdio.h> 

int main (int argc, char *argv[]) { 

    int n; 
    for (n=0; n<10; n++) { 
       printf("Print Number: %d\n", n); 
    } 
    return 0; 
} 

编译为调试版可执行文件

gcc example.c -o example.bin -g

创建文件并从文件.debug中删除调试部分。example.bin

objcopy --only-keep-debug example.bin example.debug
strip -g example.bin

将它们连接在一起。添加。.gnu_debuglinkexample.bin

objcopy --add-gnu-debuglink=example.bin.debug example.bin

那么你有:

[user@localhost myctest]$ readelf --debug-dump example.bin 
Contents of the .gnu_debuglink section:

  Separate debug info file: example.bin.debug
  CRC value: 0xefae614e

  1. 在我的 Fedora Workstation x86_64 发行版本中,默认情况下不安装这些调试包。我认为调试文件不应该安装在生产环境中。

  2. 那是为了堆栈跟踪

堆栈跟踪应如下所示:

Reading symbols from example.bin...done.
(gdb) start
Temporary breakpoint 1 at 0x401135: file example.c, line 6.
Starting program: /home/codc/works/cpp/example.bin 
warning: Loadable section ".note.gnu.property" outside of ELF segments

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffd5d8) at example.c:6
6       for (n=0; n<10; n++) {
(gdb) break printf
Breakpoint 2 at 0x7ffff7e32100: file printf.c, line 28.
(gdb) commands 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>backtrace
>continue
>end
(gdb) continue
Continuing.

Breakpoint 2, __printf (format=0x402010 "Print Number: %d\n") at printf.c:28
28  {
#0  __printf (format=0x402010 "Print Number: %d\n") at printf.c:28
#1  0x0000000000401152 in main (argc=1, argv=0x7fffffffd5d8) at example.c:7
Print Number: 0

Breakpoint 2, __printf (format=0x402010 "Print Number: %d\n") at printf.c:28
28  {
#0  __printf (format=0x402010 "Print Number: %d\n") at printf.c:28
#1  0x0000000000401152 in main (argc=1, argv=0x7fffffffd5d8) at example.c:7
Print Number: 1

相关内容