Home » Linux » How do I prepend a directory the library path when loading a core file in gdb on Linux

How do I prepend a directory the library path when loading a core file in gdb on Linux

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have a core file generated on a remote system that I don’t have direct access to. I also have local copies of the library files from the remote system, and the executable file for the crashing program.

I’d like to analyse this core dump in gdb.

For example:

gdb path/to/executable path/to/corefile

My libraries are in the current directory.

In the past I’ve seen debuggers implement this by supplying the option “-p .” or “-p /=.”; so my question is:

How can I specify that libraries be loaded first from paths relative to my current directory when analysing a corefile in gdb?

Answers:

Start gdb without specifying the executable or core file, then type the following commands:

set solib-absolute-prefix ./usr
file path/to/executable
core-file path/to/corefile

You will need to make sure to mirror your library path exactly from the target system. The above is meant for debugging targets that don’t match your host, that is why it’s important to replicate your root filesystem structure containing your libraries.

If you are remote debugging a server that is the same architecture and Linux/glibc version as your host, then you can do as fd suggested:

set solib-search-path <path>

If you are trying to override some of the libraries, but not all then you can copy the target library directory structure into a temporary place and use the solib-absolute-prefix solution described above.

Questions:
Answers:

I’m not sure this is possible at all within gdb but then I’m no expert.

However I can comment on the Linux dynamic linker. The following should print the path of all resolved shared libraries and the unresolved ones.

ldd path/to/executable

We need to know how your shared libraries were linked with your executable. To do this, use the following command:

readelf -d path/to/executable | grep RPATH
  • Should the command print nothing, the dynamic linker will use standard locations plus the LD_LIBRARY_PATH environment variable to find the shared libraries.

  • If the command prints some lines, the dynamic linker will ignore LD_LIBRARY_PATH and use the hardcoded rpaths instead.

    If the listed rpaths are absolute, the only solution I know is to copy (or symlink) your libraries to the listed locations.

    If the listed rpaths are relative, they will contain a $ORIGIN which will be replaced at run time by the path of the executable. Move either the executable or the libraries to match.

For further informations, you could start with:

man ld.so

Questions:
Answers:

I found this excerpt on developer.apple.com

set solib-search-path path

If this variable is set, path is a
colon-separated list of directories to
search for shared libraries.
solib-search-path' is used after
solib-absolute-prefix’ fails to
locate the library, or if the path to
the library is relative instead of
absolute. If you want to use
solib-search-path' instead of
solib-absolute-prefix’, be sure to
set `solib-absolute-prefix’ to a
nonexistant directory to prevent GDB
from finding your host’s libraries.

EDIT:

I don’t think using the above setting prepends the directories I added, but it does seem to append them, so files missing from my current system are picked up in the paths I added. I guess setting the solib-absolute-prefix to something bogus and adding directories in the solib-search-path in the order I need might be a full solution.

Questions:
Answers:

You can also just set LD_PRELOAD to each of the libraries or LD_LIBRARY_PATH to the current directory when invoking gdb. This will only cause problems if gdb itself tries to use any of the libraries you’re preloading.

Questions:
Answers:

One important note:

if you’re doing a cross compiling and trying to debug with gdb, then
after you’ve done
file ECECUTABLE_NAME if you see smth. like :

Using host libthread_db library "/lib/libthread_db.so.1"

then check whether you have libthread_db for your target system. I found a lot of similar problems on the web. Such problem cannot be solved just using “set solib-“, you has to build libthread_db using your cross-compiler as well.