c++linuxdebugginggccgdb

Fail to load debug symbols from external file when debugging with gdb


I am investigating how to use gdb for debugging with symbols in external file.

I build a small executable that depend og and equally small shared library.

I build the executable with cmake producing the following g++ command (I have left out various includes for simplicity):

g++ -DSharedLib_EXPORTS -m64 -Wall -O0 -g -ggdb -std=c++17 -fPIC -MD -MT SharedLib/CMakeFiles/SharedLib.dir/src/SharedLib.cpp.o -MF CMakeFiles/SharedLib.dir/src/SharedLib.cpp.o.d -o CMakeFiles/SharedLib.dir/src/SharedLib.cpp.o -c SharedLib/src/SharedLib.cpp
g++ -m64 -Wall -O0 -g -ggdb -std=c++17 -fPIE -MD -MT Executable/CMakeFiles/Executable.dir/src/Executable.cpp.o -MF CMakeFiles/Executable.dir/src/Executable.cpp.o.d -o CMakeFiles/Executable.dir/src/Executable.cpp.o -c Executable/src/Executable.cpp
g++ -fPIC -m64 -Wall -O0 -g -ggdb -m64 -shared -Wl,-soname,libSharedLib.so -o libSharedLib.so CMakeFiles/SharedLib.dir/src/SharedLib.cpp.o -ldl -lrt -lpthread
g++ -m64 -Wall -O0 -g -ggdb -m64 CMakeFiles/Executable.dir/src/Executable.cpp.o -o Executable libSharedLib.so -lrt -ldl -lpthread

I then copy/strip symbols from both the shared library and the executable with:

objcopy --only-keep-debug Executable symbols/Executable.debug
objcopy --add-gnu-debuglink=symbols/Executable.debug Executable
strip Executable

Inspecting the stripped executable with readelf --string-dump=.gnu_debuglink Executable shows that there is indeed a debug link in the file:

String dump of section '.gnu_debuglink':
  [     0]  Executable.debug
  [    14]  ^�$�

I then end up with two .debug files in the symbols directory, one for the executable and then one for the shared library.

I then fire up gdb to debug Executable (I have deliberately added a segmentation fault in the shared library to test it with gdb):

(gdb) set debug-file-directory symbols
(gdb) file Executable
Reading symbols from Executable...
(No debugging symbols found in Executable)
(gdb)

It feels like it completely ignores the set debug-file-directory symbols? What am I doing wrong?

Regards Klaus


Solution

  • As @ssbssa said in a comment, GDB's lookup for split debug files isn't doing what you think.

    First, when you do:

    objcopy --add-gnu-debuglink=symbols/Executable.debug Executable
    

    The symbols/ bit is discarded, this is confirmed by your dump of the debug link section.

    So GDB will look for the file named in the debug link section:

    1. In the same directory as the executable,
    2. In a .debug/ subdirectory, and then
    3. In any debug-directories, but using the path to the executable.

    So, if your executable is /opt/bin/Executable, the debug link is Executable.debug, and the debug-file-directories is /symbols, GDB will look in:

    1. /opt/bin/Executable.debug
    2. /opt/bin/.debug/Executable.debug
    3. /symbols/opt/bin/Executable.debug

    You can get more insight into where GDB is looking by turning on a GDB maintainer debug flag:

    (gdb) set debug separate-debug-file on
    

    Then run your file command and GDB will print where it's looking for debug information.