让gdb再次搜索符号文件
Make gdb search for symbol files again
我的发行版 (Debian) 在单独的包中提供调试文件。所以经常发生的事情是,我 运行 一个程序 gdb
直到它崩溃,以便为错误报告获得可用的回溯。但是bt
有点没用,缺少符号信息——因为我没有安装对应的-dbg
包。
如果我现在安装这个包,有没有办法让gdb
再次搜索符号文件,而不丢失我当前的回溯?
我将建议使用 gdb gcore
命令的替代方法,可能适合您。
这是 gcore 描述:
(gdb) help gcore
Save a core file with the current state of the debugged process.
Argument is optional filename. Default filename is 'core.<process_id>'
所以我有一个导致崩溃的程序:
include <iostream>
int f()
{
time_t curr_ts = time(0);
std::cout << "Before crash " << curr_ts << std::endl;
int * ptr = 0;
*ptr = *ptr +1 ;
std::cout << "After crash " << curr_ts << std::endl;
return *ptr;
}
int main()
{
std::cout << "Before f() " << std::endl;
f();
std::cout << "After f() " << std::endl;
return 0;
}
我用调试信息编译了它。但是我将带有调试信息的可执行文件放在存档中,测试使用剥离版本。
因此它在 gdb 下崩溃:
$ gdb ./a.out
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/crash/a.out
Before f()
Before crash 1435322344
Program received signal SIGSEGV, Segmentation fault.
0x000000000040097d in ?? ()
(gdb) bt
#0 0x000000000040097d in ?? ()
#1 0x00000000004009e0 in ?? ()
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
#3 0x00000000004007f9 in ?? ()
#4 0x00007fffffffde58 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffe1a9 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb) gcore crash2.core
Saved corefile crash2.core
我简单地用gcore
生成核心文件然后离开gdb。然后我从存档中得到带有调试符号的版本,我可以看到所有符号:
$ gdb ./a.out ./crash2.core
Reading symbols from ./a.out...done.
warning: exec file is newer than core file.
[New LWP 15215]
Core was generated by `/home/crash/a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
(gdb) info locals
curr_ts = 1435322344
ptr = 0x0
更新
如果你 set backtrace past-main on
你至少会看到这个 __libc_start_main
。如果你只分析核心文件(甚至可能没有保存在那里)保存机智 gcore
:
,则上面 __libc_start_main
的内容不会被打印出来
$ gdb ./a.out crash2.core
Reading symbols from ./a.out...done.
warning: exec file is newer than core file.
[New LWP 15215]
Core was generated by `/home/crash/a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) set backtrace past-main on
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
Backtrace stopped: Cannot access memory at address 0x4007d0
(gdb)
但是如果我用我的测试程序(其中包含调试信息)在 gdb
下重现崩溃,我可以看到所有内容(参见 set backtrace past-main on
&& set backtrace past-entry on
):
$ gdb ./a.out
Reading symbols from ./a.out...done.
(gdb) r
Starting program: /home/crash/a.out
Before f()
Before crash 1435328858
Program received signal SIGSEGV, Segmentation fault.
0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
(gdb) set backtrace past-main on
(gdb) set backtrace past-entry on
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
#3 0x00000000004007f9 in _start ()
#4 0x00007fffffffde58 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffe1a9 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb)
有一个技巧可以让 gdb 再次尝试读取符号文件:
(gdb) nosharedlibrary
(gdb) sharedlibrary
第一个命令告诉它忘记它拥有的所有符号信息,第二个命令告诉它重新读取它。
我的发行版 (Debian) 在单独的包中提供调试文件。所以经常发生的事情是,我 运行 一个程序 gdb
直到它崩溃,以便为错误报告获得可用的回溯。但是bt
有点没用,缺少符号信息——因为我没有安装对应的-dbg
包。
如果我现在安装这个包,有没有办法让gdb
再次搜索符号文件,而不丢失我当前的回溯?
我将建议使用 gdb gcore
命令的替代方法,可能适合您。
这是 gcore 描述:
(gdb) help gcore
Save a core file with the current state of the debugged process.
Argument is optional filename. Default filename is 'core.<process_id>'
所以我有一个导致崩溃的程序:
include <iostream>
int f()
{
time_t curr_ts = time(0);
std::cout << "Before crash " << curr_ts << std::endl;
int * ptr = 0;
*ptr = *ptr +1 ;
std::cout << "After crash " << curr_ts << std::endl;
return *ptr;
}
int main()
{
std::cout << "Before f() " << std::endl;
f();
std::cout << "After f() " << std::endl;
return 0;
}
我用调试信息编译了它。但是我将带有调试信息的可执行文件放在存档中,测试使用剥离版本。
因此它在 gdb 下崩溃:
$ gdb ./a.out
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/crash/a.out
Before f()
Before crash 1435322344
Program received signal SIGSEGV, Segmentation fault.
0x000000000040097d in ?? ()
(gdb) bt
#0 0x000000000040097d in ?? ()
#1 0x00000000004009e0 in ?? ()
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
#3 0x00000000004007f9 in ?? ()
#4 0x00007fffffffde58 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffe1a9 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb) gcore crash2.core
Saved corefile crash2.core
我简单地用gcore
生成核心文件然后离开gdb。然后我从存档中得到带有调试符号的版本,我可以看到所有符号:
$ gdb ./a.out ./crash2.core
Reading symbols from ./a.out...done.
warning: exec file is newer than core file.
[New LWP 15215]
Core was generated by `/home/crash/a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
(gdb) info locals
curr_ts = 1435322344
ptr = 0x0
更新
如果你 set backtrace past-main on
你至少会看到这个 __libc_start_main
。如果你只分析核心文件(甚至可能没有保存在那里)保存机智 gcore
:
__libc_start_main
的内容不会被打印出来
$ gdb ./a.out crash2.core
Reading symbols from ./a.out...done.
warning: exec file is newer than core file.
[New LWP 15215]
Core was generated by `/home/crash/a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) set backtrace past-main on
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
Backtrace stopped: Cannot access memory at address 0x4007d0
(gdb)
但是如果我用我的测试程序(其中包含调试信息)在 gdb
下重现崩溃,我可以看到所有内容(参见 set backtrace past-main on
&& set backtrace past-entry on
):
$ gdb ./a.out
Reading symbols from ./a.out...done.
(gdb) r
Starting program: /home/crash/a.out
Before f()
Before crash 1435328858
Program received signal SIGSEGV, Segmentation fault.
0x000000000040097d in f () at main.cpp:8
8 *ptr = *ptr +1 ;
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
(gdb) set backtrace past-main on
(gdb) set backtrace past-entry on
(gdb) bt
#0 0x000000000040097d in f () at main.cpp:8
#1 0x00000000004009e0 in main () at main.cpp:17
#2 0x000000314981ed1d in __libc_start_main () from /lib64/libc.so.6
#3 0x00000000004007f9 in _start ()
#4 0x00007fffffffde58 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffe1a9 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb)
有一个技巧可以让 gdb 再次尝试读取符号文件:
(gdb) nosharedlibrary
(gdb) sharedlibrary
第一个命令告诉它忘记它拥有的所有符号信息,第二个命令告诉它重新读取它。