在为 gdb 安装那些缺少的调试信息包后,我能做些什么不同的事情?

What can I do differently after I install those missing debug info packages for gdb?

我有全新安装 CentOS Linux release 7.2.1511 (Core)gdb 版本是 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7

我看到了 Missing separate debuginfos 警告

Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64

我了解到:

Missing glibc-2.17-157.el7_3.1.x86_64 will only prevent you from stepping through GLIBC itself.

来自这个答案Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.1.x86_64


现在我已经成功安装了所有这些调试信息包。但我看不出有什么不同。我现在可以使用安装的这些额外包做哪些额外的事情

以这个C++程序为例:

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main(){
        vector<int> a = {1,2,3};
        vector<int> b = {4,5,6};
        map<int, vector<int>> m = {{1, a}, {2, b}};
        cout << m[1][0] << endl;
        cout << m[2][0] << endl;
}

g++ -Wall -g test.cpp -std=c++11编译。

我可以在安装这些调试信息包之前和之后单步执行 libstdc++。那有什么区别呢?

我的理解单步执行是,例如当我在cout << m[1][0] << endl;这一行按s时,gdb表明我是在 stl_map.h:481 中:

std::map<int, std::vector<int, std::allocator<int> >, std::less<int>, std::allocator<std::pair<int const, std::vector<int, std::allocator<int> > > > >::operator[](int&&) (this=0x7fffffffe3f0, 
    __k=<unknown type in /root/a.out, CU 0x0, DIE 0x7b70>) at /usr/include/c++/4.8.2/bits/stl_map.h:481
481     iterator __i = lower_bound(__k);

相关问题:Missing separate debuginfos


解决方案更新:

看完这个我明白了细节How to use debug version of libc. I also read about how separate debug info files work and tried manually redirecting gdb to find source files with set substitute-path by this answer

最终我了解了这些东西是如何协同工作的:

  1. 默认情况下,这些共享库没有在 .so

    中嵌入调试信息
  2. 并且调试信息存储在另一个目录中,gdb 将尝试从中加载。

  3. 除此之外,我还需要 list 左右的源文本文件。

So what's the difference?

不同之处在于,您现在可以列出 GLIBC 的来源(这与 libstdc++ 不同)并逐步浏览它们。

尝试 (gdb) list abort 有无 debuginfo-install

更新:

Am I able to "list soucre of libstdc++" and "step through them" without those packages?

libstdc++ 与 GLIBC 的不同之处在于它的大部分功能是由 模板 提供的,这些模板包含在您自己的源代码中。当你通过例如/usr/include/c++/4.8.2/bits/stl_map.h,这就是 正在发生的事情。

但您可能仍然需要 debuginfo-install libstdc++-4.8.5-44.el7.x86_64 才能列出并单步执行 libstdc++ 的部分 而不是 所提供 [=] 的部分63=].

IIRC、std::basic_string<char, ...> 的实现和 std::basic_ios 的各个部分都属于这一类。您可以 运行 nm -C libstdc++.so.6 | egrep ' [TW] ' 查看此类符号的列表。

更新二:

Are those installed debug infos just glibc and gcc soure text files?

没有

调试信息是一组文件,它允许调试器将库的 .text 中的特定偏移量与在该偏移量处生成机器代码的源代码相关联。它还对参数和变量的类型、局部变量在给定函数中的位置等进行编码。您可以阅读更多关于调试信息 here.

一些系统上,调试信息包包含库的源代码,但这在[=64]中并不通用=] 系统,并且不是调试信息包的 main 目的(如果你想要的只是源代码,你可以安装 source 包) .

感谢@Employed Russian 的回答,现在我知道了确切的区别。

这是我从 2 个全新安装的 CentOS 7.2 中观察到的,一个安装了调试信息,一个没有。

OS版本:CentOS Linux release 7.2.1511 (Core)

GDB 版本:GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7

测试程序:

#include <iostream>
#include <vector>
#include <map>
#include <stdlib.h>
#include <signal.h>
#include <string>
using namespace std;

int main(){
        string s = "123";
        vector<int> a = {1,2,3};
        vector<int> b = {4,5,6};
        map<int, vector<int>> m = {{1, a}, {2, b}};
        cout << m[1][0] << endl;
        cout << m[2][0] << endl;
        cout << s << endl;
        abort();
        //raise(3);
}

  1. 我通过这个 answer
  2. 安装了调试包

并由 运行宁

debuginfo-install glibc-2.17-307.el7.1.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64

我看到安装了这些软件包。

========================================================================================================================
 Package                                      Arch              Version                      Repository            Size
========================================================================================================================
Installing:
 gcc-debuginfo                                x86_64            4.8.5-44.el7                 debuginfo            195 M
 glibc-debuginfo                              x86_64            2.17-307.el7.1               debuginfo            9.5 M
 nss-softokn-debuginfo                        x86_64            3.44.0-8.el7_7               debuginfo            2.1 M
 yum-plugin-auto-update-debug-info            noarch            1.1.31-54.el7_8              os                    29 k
Installing for dependencies:
 gcc-base-debuginfo                           x86_64            4.8.5-44.el7                 debuginfo            2.9 M
 glibc-debuginfo-common                       x86_64            2.17-307.el7.1               debuginfo            9.7 M

有趣的是没有安装 libstdc++-debuginfo 之类的东西,尽管 libstdc++ 显示在“缺少单独的调试信息警告”中。 有人能解释一下吗?


  1. 在两台服务器上,我用g++ -g -Wall test.cpp -std=c++11和运行gdb ./a.out
  2. 编译了测试程序
  • b main, r.

在安装调试信息的服务器上,我可以进入string s = "123";abort 环顾四周。在另一台服务器上,当我按 s.

时,它只是越界(就像按 n

安装调试信息的服务器:

Breakpoint 1, main () at test.cpp:10
10          string s = "123";
(gdb) s
std::allocator<char>::allocator (this=0x7fffffffe45b)
    at /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/allocator.h:113
113       allocator() throw() { }
(gdb) s
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0x7fffffffe450, 
    __s=0x403b73 "123", __a=...)
    at /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_string.tcc:212
212     basic_string<_CharT, _Traits, _Alloc>::
(gdb) s


16          cout << s << endl;
(gdb) n
123
17      abort();
(gdb) s
__GI_abort () at abort.c:52
52  {
(gdb) list
47  
48  
49  /* Cause an abnormal program termination with core-dump.  */
50  void
51  abort (void)
52  {
53    struct sigaction act;
54    sigset_t sigs;
55  
56    /* First acquire the lock.  */

这就是不同之处。