gdb won't load shared libs symbols, not even libc.so (musl), when loading a core file

2

I'm trying to debug a program running remotely on a board with a MIPS cpu, using musl for its libc. If I start gdbserver on the board, set the sysroot via set sysroot /path/to/sysroot and connect live from gdb, I get a meaningful stack trace (which took hours of effort due to musl lacking CFI directives on MIPS and me having to add them, but that's a separate issue), and I can see gdb loading symbols from libc.so from the sysroot.

On the other hand, if I let that program crash and generate a core dump (I used kill -6 <pid> to force one for testing), gdb will load symbols from the binary, but not any of its shared libraries, not even libc.so. While other shared libs are nice but not essential, without debug info from libc.so, gdb cannot resolve stack traces and they all look like garbage.

Successful live gdb session

$ mipsel-poky-linux-gdb -iex "set sysroot /path/to/sysroot" /path/to/testprog
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 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 "--host=x86_64-pokysdk-linux --target=mipsel-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /path/to/testprog...done.
(gdb) 
(gdb) target extended-remote remote-hostname:10000
Remote debugging using remote-hostname:10000
Reading symbols from /path/to/sysroot/lib/ld.so.1...done.
__cp_end () at src/thread/mips/syscall_cp.s:38
38      beq     $7, $0, 1f
(gdb) bt
#0  __cp_end () at src/thread/mips/syscall_cp.s:38
#1  0x77eff348 in __syscall_cp_c (nr=4029, u=<optimized out>, v=<optimized out>, w=<optimized out>, x=0, y=0, z=0)
    at src/thread/pthread_cancel.c:33
#2  0x77f0b4b0 in pause () at src/unistd/pause.c:7
#3  0x556ecd3c in core_run (argc=1, argv=0x7f7bf4a4) at /path/to/source-file.cpp:461
#4  0x77e93d28 in libc_start_main_stage2 (main=0x556b1ac0 <main(int, char**)>, argc=1, argv=0x7f7bf4a4)
    at src/env/__libc_start_main.c:94
#5  0x556eb890 in _start_c (p=<optimized out>) at crt/crt1.c:18
#6  0x556eb850 in _start () at /path/to/header-file.hpp:130
Backtrace stopped: frame did not save the PC

(note: in the above I replaced internal paths/file names/etc with placeholders)

Unsuccessful core dump gdb session

$ mipsel-poky-linux-gdb -iex "set verbose on" -iex "set sysroot /path/to/sysroot" /path/to/testprog core
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 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 "--host=x86_64-pokysdk-linux --target=mipsel-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /path/to/testprog...done.
Reading in symbols for /path/to/source/main.cpp...done.
[New LWP 1285]
[New LWP 1408]
[New LWP 1409]
[New LWP 1410]
[New LWP 1412]
[New LWP 1407]
[New LWP 1401]
[New LWP 1402]
[New LWP 1403]
[New LWP 1404]
Using PIE (Position Independent Executable) displacement 0x555c4000 for "/path/to/testprog".

warning: platform-specific solib_create_inferior_hook did not load initial shared libraries.
Reading symbols from system-supplied DSO at 0x7ff2b000...(no debugging symbols found)...done.
Core was generated by `/remote/path/to/testprog'.
Program terminated with signal SIGABRT, Aborted.
#0  0x77e80204 in ?? ()
[Current thread is 1 (LWP 1285)]
(gdb) bt
warning: GDB can't find the start of the function at 0x77e80204.

    GDB is unable to find the start of the function at 0x77e80204
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
    This problem is most likely caused by an invalid program counter or
stack pointer.
    However, if you think GDB should simply search farther back
from 0x77e80204 for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
#0  0x77e80204 in ?? ()
(gdb)

(note: in the above I replaced internal paths/file names/etc with placeholders)

Things I tried

I tried several things, including using set solib-search-path instead of set sysroot, directly telling gdb to load the library via add-symbol-file /path/to/libc.so and even add-symbol-file /path/to/libc.so 0xdeadbeef where 0xdeadbeef is really the address the library was loaded, obtained via readelf. In this last case, gdb finally loaded the symbols, but clearly something wasn't right, probably the address I passed was incorrect. Thing is, I shouldn't have to do this, gdb should find this information in the core dump and load the libraries! How do I make it do that, and why wouldn't it do it in the first place?

linux
debugging
gdb
mips
musl
asked on Stack Overflow Jan 25, 2020 by Daniele

1 Answer

0

Give /path/to/libc.so to gdb what does it show ? can it read debug symbols ? $ gdb /path/to/libc.so

Generally libc.so does not contain the debug symbols itself, instead it contain a link to the file which contains its debug symbols

In Linux, debug symbols can be in:

/usr/lib/debug

/usr/bin/.debug

See where the gdb is looking for separate debug symbol files:

(gdb) show debug-file-directory

If needed you can set to another if that contains the desired debug symbol file

You can know the name of debug symbol file pointed to by a .so like below:

$ readelf -x.gnu_debuglink /lib/x86_64-linux-gnu/libc.so.6

Hex dump of section '.gnu_debuglink':
  0x00000000 6c696263 2d322e32 372e736f 00000000 libc-2.27.so....
  0x00000010 48c02c04                            H.,.

There libc-2.27.so is name of debug symbol file which is actually in /usr/lib/debug//lib/x86_64-linux-gnu/ on my system

OR,

add-symbol-file /path/to/libc.so #here you should give file which contains debug symbols not the one which just has link to debug symbol file, because it does not contain path(see above output), the debug symbol file is found with help and use of debug-file-directory

answered on Stack Overflow Feb 2, 2020 by Sumit

User contributions licensed under CC BY-SA 3.0