为什么 gdb -s 选项不加载符号文件?

Lon*_*ner 1 gdb

我正在尝试创建一个核心转储并使用 gdb 对其进行分析。这是我编写的用于创建核心转储的代码。

#include <iostream>

void bar()
{
    char *p = (char *) 123;
    std::cout << "bar start\n";
    std::cout << *p << "\n";
    std::cout << "bar end\n";
}

void foo()
{
    std::cout << "foo start\n";
    bar();
    std::cout << "foo end\n";
}

int main()
{
    foo();
}
Run Code Online (Sandbox Code Playgroud)

这是我的 Makefile。

all:
        g++ -g foo.cc -o foo
        objcopy --only-keep-debug foo foo.dbg
        objcopy --strip-debug foo

clean:
        rm -rf core* foo
Run Code Online (Sandbox Code Playgroud)

运行make和后./foo,这就是我的目录的样子。

# ls
core.28091  foo  foo.cc  foo.dbg  Makefile
Run Code Online (Sandbox Code Playgroud)

我能够像这样分析核心转储。我通过指定可执行文件和核心文件作为命令行参数来启动 gdb。然后我使用命令从 foo.dbg 加载符号symbol-file foo.dbg

[root@centos crash]# gdb foo core.28091
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lab/crash/foo...(no debugging symbols found)...done.
[New Thread 28091]
Missing separate debuginfo for
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/81/a81be2e44c93640adedb62adc93a47f4a09dd1
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./foo'.
Program terminated with signal 11, Segmentation fault.
#0  0x000000000040076f in bar() ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 libgcc-4.4.7-4.el6.x86_64 libstdc++-4.4.7-4.el6.x86_64
(gdb) symbol-file foo.dbg
Reading symbols from /root/lab/crash/foo.dbg...done.
(gdb) bt
#0  0x000000000040076f in bar () at foo.cc:8
#1  0x00000000004007b7 in foo () at foo.cc:15
#2  0x00000000004007d1 in main () at foo.cc:21
(gdb) list
12      void foo()
13      {
14          std::cout << "foo start\n";
15          bar();
16          std::cout << "foo end\n";
17      }
18
19      int main()
20      {
21          foo();
(gdb)
Run Code Online (Sandbox Code Playgroud)

但是,我也想在命令行参数中指定符号文件名。但这似乎不起作用。请参阅下面的输出。

[root@centos crash]# gdb -s foo.dbg foo core.28091
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lab/crash/foo...(no debugging symbols found)...done.
[New Thread 28091]
Missing separate debuginfo for
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/81/a81be2e44c93640adedb62adc93a47f4a09dd1
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./foo'.
Program terminated with signal 11, Segmentation fault.
#0  0x000000000040076f in bar() ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 libgcc-4.4.7-4.el6.x86_64 libstdc++-4.4.7-4.el6.x86_64
(gdb) bt
#0  0x000000000040076f in bar() ()
#1  0x00000000004007b7 in foo() ()
#2  0x00000000004007d1 in main ()
(gdb) list
No symbol table is loaded.  Use the "file" command.
Run Code Online (Sandbox Code Playgroud)

为什么它说没有加载符号表,即使我已将其指定为选项的参数-s

Mar*_*ick 5

它看起来像是 gdb 中的一个错误。gdb 设置symarg为后面的参数-s,但随后在代码中,它无条件设置symarg为可执行文件的名称。建议的最小差异如下:

$ diff -C 1 main.c.orig main.c
*** main.c.orig 2014-07-29 08:37:42.000000000 -0400
--- main.c      2014-09-02 16:27:54.079039046 -0400
***************
*** 864,866 ****
        }
!       symarg = argv[optind];
        execarg = argv[optind];
--- 864,866 ----
        }
!       if (symarg == NULL) symarg = argv[optind];
        execarg = argv[optind];
***************
*** 877,879 ****
        {
!         symarg = argv[optind];
          execarg = argv[optind];
--- 877,879 ----
        {
!         if (symarg == NULL) symarg = argv[optind];
          execarg = argv[optind];
Run Code Online (Sandbox Code Playgroud)