Make gdb search for symbol files again

1.5k views Asked by At

My distribution (Debian) ships debug files in separate packages. So what happens often is that I run a program in gdb until it crashes, in order to obtain a usable backtrace for a bug report. But bt is rather useless, missing the symbol information – because I did not install the corresponding -dbg package.

If I install the package now, is there a way to make gdb search for the symbol files again, without losing my current backtrace?

2

There are 2 answers

1
Tom Tromey On BEST ANSWER

There is a trick you can use to make gdb try to read symbol files again:

(gdb) nosharedlibrary
(gdb) sharedlibrary

The first command tells it to forget all the symbol information it has, and the second command tells it to re-read it.

2
AudioBubble On

I am going to suggest an alternative approach with gdb gcore command, possibly it is suitable for you.

This is gcore description:

(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>'

So I have a program that causes a crash:

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;
}

I compiled it with debug info. However I put the executable with debug info in an archive and for tests use a stripped version.

So it crashes under 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

I simply generate core file with gcore and leave gdb. Then I get from the archive the version with debug symbols and I can see all symbols:

$ 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

Update

if you set backtrace past-main on you will see at least this __libc_start_main. What is above __libc_start_main is not printed if you analyze only core file (possibly even not saved there) saved wit gcore:

$ 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) 

But if I reproduce the crash under gdb with my test program (with debug info in it) I can see all (see 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)