solib-absolute-prefix vs. solib-search-path in GDB - gdb

I read the description of both but I don't yet understand the difference. Can anyone help me understand the differences?
set solib-absolute-prefix -
Specifies the local directory that contains copies of target libraries in the
corresponding subdirectories. This option is useful when debugging with gdbserver.
.
set solib-search-path command -
Specifies directories where GDB will search for shared libraries with symbols. This option
is useful when debugging with gdbserver.
Thanks.

The wording is quite unclear :-(
Assume that your target loaded /usr/lib/libfoo.so, and that on the host (where GDB is running), you have a copy of the entire target tree in /tmp/host. That is, a copy of target's /usr/lib/libfoo.so is found on host in /tmp/host/usr/lib/libfoo.so.
Then, the following commands are almost equivalent:
set solib-absolute-prefix /tmp/host
set solib-search-path /tmp/host/usr/lib
Now consider what happens if you also have /usr/local/lib/libbar.so on target, and a copy of it in /tmp/host/usr/local/lib/libbar.so.
The solib-absolute-prefix as set above is still good to locate libbar.so, but solib-search-path would have to be modified like so:
set solib-search-path /tmp/host/usr/lib:/tmp/host/usr/local/lib
To summarize, if you have entire target tree under a single host $ROOT, then just set solib-absolute-prefix to $ROOT and you should be good.
But if you have to "assemble" target paths from multiple disjoint trees, then solib-search-path with multiple paths will allow GDB to still find correct libraries.

Related

How to specify .so path to use with GDB whan analysing dump file?

I have a crash dump that I want to analyse with GDB on different computer. Crashed application uses several shared libraries (*.so files). I want GDB to load symbols from some of them but I can't put all of them in the original path.
Adding LD_LIBRARY_PATH to the environment doesn't help when working with dumps. When I type info shared it shows full (non-relative) paths:
(gdb) info shared
From To Syms Read Shared Object Library
0x00007fad4fb7f220 0x00007fad4fb80179 Yes /lib/x86_64-linux-gnu/libdl.so.2
...
No /opt/app/libXXX.so
...
How to specify different path for the example libXXX.so (from gdb command line or command prompt)?
The set solib-search-path option is for that purpose. Documentation says it is ment for using with gdbserver but also works with dump analysis. By default, it is set to ., so the directory that gdb is run from.
BUT: for some reason it doesn't work out of the box (at least with gdb 10.2). I don't know the reason, but I know a workaround: just type set solib-search-path . as a first command after entering gdb prompt. The output is following for me:
(gdb) set solib-search-path .
Reading symbols from /home/example/path/libXXX.so...
Of course one can type any path she want instead of ..

golang os.Setenv does not work in cgo C.dlopen?

For some reason, I can not set $LD_LIBRARY_PATH to global env. I try to set it up in golang code use os.Setenv.
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
I use another C++ function to get $LD_LIBRARY_PATH, it shows corretly.
But lib returns '<nil>', and C.dlerror() shows
>> %!(EXTRA string=libhasp_linux_x86_64_demo.so: cannot open shared object file: No such file or directory)
Means $LD_LIBRARY_PATH does not work in dlopen, cgo can not find depend libraries.
I don't know why.Hope some one can help me.Thanks!
It looks like you're trying to call os.Setenv("LD_LIBRARY_PATH", ...) and then C.dlopen() from within the same process.
From the man page dlopen(3):
Otherwise, the dynamic linker searches for the object as follows
...
If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched.
The key phrase being, at the time the program is started. We can see in the implementation for dlopen in the glibc source elf/dl-load.c that it looks at a global variable __rtld_env_path_list.dirs that has already been set when searching for libraries to load; it does not look at the current value of $LD_LIBRARY_PATH.
If you want to use LD_LIBRARY_PATH to find things in C.dlopen, then you'll need to set it before your process starts (by running e.g. LD_LIBRARY_PATH=/my/path go run my-app.go).
As KJ Tsanaktsidis correctly answered, LD_LIBRARY_PATH has no effect after the process has started; you must set it before starting the process.
A common technique is to examine current value of LD_LIBRARY_PATH, and if it's not to your liking, set it to new value and re-exec the process.
That said, it's not clear why you want set LD_LIBRARY_PATH in the first place. dlopen will happily open a library which is not on LD_LIBRARY_PATH if you invoke dlopen with absolute path. That is, instead of doing this:
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
do this:
lib := C.dlopen(C.CString(absolute_path_to_library), C.RTLD_LAZY)

Unable to load shared library : libxerces.so

While running the application developed by other person, getting the following error
./appln: error while loading shared libraries: libxerces-c.so.28: cannot open shared object file: No such file or directory
And if I run ldd command:
# ldd appln
linux-gate.so.1 => (0x00e20000)
libdl.so.2 => /lib/libdl.so.2 (0x00a61000)
libxerces-c.so.28 => not found
I already have that libxerces-c.so.28 file in current folder. Please help me how to resolve that error
You need to put libxerces-c.so somewhere in the library path. Probably current folder is not searched for libraries. Try putting it in /usr/local/lib
Evidently "the current folder" isn't in the run time search path used by your executable. I'm assuming that you are on linux (linux-gate.so.1).
You need to ensure that "the current" directory is under the search path. You can do this at link time by using the -rpath option to the linker (-R is also accepted) or -Wl,-rpath,<dir> if you are invoking the linker through the compiler front end. This embeds a search path to be used at run time into your program.
Consider how you want the program to be installed, though. There's no point in adding a path that is specific to your development environment. You might want to consider using $ORIGIN or a $ORIGIN relative path which tells the run time linker to look for shared objects in the location containing (or relative to) the executable. You should always avoid adding . to the run time search path; your program shouldn't behave differently depending on the current directory of the process which invokes it.
As a temporary measure you can set the environment variable LD_LIBRARY_PATH to override the embedded and system search paths but it is normally a bad idea to rely on LD_LIBRARY_PATH overrides for a final installation.
By default .so files are NOT being searched in the current folder (they should be in /usr/lib, etc).
To add the current directory for .so lookup use:
LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ./appln
When adding new "local system" libraries (e.g. in /usr/local/lib/) you better add that directory (/usr/local/lib/) once in your /etc/ld.so.conf and you should run ldconfig to update the linker cache (every time you add something inside /usr/local/lib/)
See ldconfig(8), ld.so(8), ldd(1), dlopen(3)
If you want your own libraries, set LD_LIBRARY_PATH to a directory containing them (e.g. $HOME/lib/ and to standard directories, e.g.
export LD_LIBRARY_PATH=$HOME/lib:/usr/lib:/usr/local/lib
in your ~/.bashrc (but I dislike that confusing practice, and prefer to manage my /usr/local/lib/).
You could also use some -Wl,-rpath argument but I really dislike that also.
Read also Program Library HowTo and Drepper's paper: How To Write Shared Libraries

what command in gdb is same as pathmap in dbx?

When I use gdb on a coredump it reports some .so it cannot find in a certain path. For example:
Symbol file not found for /root/a/xx.so
I do not have administrator rights to create a directory in root, but I do have the xx.so, and in dbx, I can use pathmap to change the path where I can continue the debug. But in gdb I cannot find the same command.
In addition, I do not have the rights to change the compiler command. That is to say, I can't change the linker path to re-compile.
It sounds like you want set solib-search-path, which takes a colon-delimited list of directory names to search for shared libraries when searching in sysroot fails.
A related command, set sysroot (a.k.a set solib-absolute-prefix), allows you to set any directory as the root used for loading libraries with absolute path names, but you would need to insure that the libraries are laid out in the proper directory structure under the new root, and it sounds like you don't want to do this.
You can try dir command to change to the location of the file.
The command you are looking for is
set substitute-path <from> <to>

How to find "my" lib directory?

I'm developing a C++ program under Linux. I want to put some stuff (to be specific, LLVM bitcode files, but that's not important) in libraries, so I want the following directory structure:
/somewhere/bin/myBin
/somewhere/lib/myLib.bc
How do I find the lib directory? I tried to compute a relative part from argv[0], but if /somewhere is in my PATH, argv[0] will just contain myBin. Is there some way to get this path? Or do I have to set it at compile time?
How do GNU autotools deal with this? What happens exactly if I supply the --prefix option to ./configure?
Edit: The word library is a bit misleading in my case. My library consist of LLVM bitcode, so it's not an actual (shared) object file, just a file I want to open from my program. You can think of it as an image or text file.
maybe what you want is :
/usr/lib
unix directory reference: http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilestruct.html
Assume your lib directory is "../lib" relative to executable
First you need to identify where myBin located, You can get it by reading /proc/self/exe
Then concat your binary file path with "../lib" will give you the lib directory.
You will have to use a compiler flag to tell the program. For example, if you have a plugin dir:
# Makefile.am
AM_CPPFLAGS = -DPLUGIN_DIR=\"${pkglibdir}\"
bin_PROGRAMS = awesome_prog
pkglib_LTLIBRARIES = someplugin.la
The list of directories to be searched is stored in the file /etc/ld.so.conf.
In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes.
LD_LIBRARY_PATH is handy for development and testing:
$ export LD_LIBRARY_PATH=/path/to/mylib.so
$ ./myprogram
[read more]
Addressing only the portion of the question "how to GNU autotools deal with this?"...
When you assign a --prefix to configure, basically two things happen: 1) it instructs the build system that everything is to be installed in ${prefix}, and 2) it looks in ${prefix}/share/config.site for any additional information about how the system is set up (it is common for that file not to exist.) It does absolutely nothing to help find libraries, but depends on the user having set up the tool chain properly. If you want to use a library in /foo/lib, you must have your toolchain set up to look there (eg, by putting /foo/lib in /etc/ld.so.conf, or by putting -L/foo/lib in LDFLAGS and "/foo/lib" in LD_LIBRARY_PATH)
The configure script relies on you to have the environment set up. It does not help you set up that environment, but does help by alerting you that you have not done so.
You could use the readlink system call on /proc/self/exe to get the path of your executable. You might then use realpath etc.