Linux find path to library

How can I find the full file path given a library name like libfoo.so.1?

Without implementing a linker or using ldd , how can I find the full path to a library? Is there a standard library available for that on Linux? (POSIX maybe?) Using ldd and grep on a file that is knowingly using libGL.so.1 , it looks like:

$ ldd /usr/bin/glxinfo | grep libGL libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f34ff796000) 

Given a library name like libGL.so.1 , how can I find the full path /usr/lib/libGL.so.1 ?. Preferably accepting an option for finding 32-bit and 64-bit libraries. If no library does that, does a program exist to do this? Something like find-library-path libGL.so.1 . The locate libGL.so.1 command does not count. I don’t want to actually load the library using dlopen or something if it executes code from that library.

5 Answers 5

Use ldconfig which is the tool that manages link space.

The -p flag lets you browse all available linkable libraries.

Thanks for your answer ,but -p prints cached entries from a file, not the current state (directories in $LD_LIBRARY_PATH are not respected for example)

@Lekensteyn If you want to find the library in any location and not rely on any mechanic that is actually used to manage libraries, find or the locate DB might be your only options. As your questions is stated, looking at the source for the loader might also be an option.

Expanding on Honky Tonk’s answer, the command echo «$(ldconfig -p | grep libGL.so.1 | tr ‘ ‘ ‘\n’ | grep /)» will give you the path alone.

If you don’t mind actually loading the library and using some nonstandard but widely-available functions, calling dladdr on any symbol from the library will return information containing the full pathname that was loaded.

I’ll have a look at the manpage, I also added another requirement to the question: the library should not execute code of the library that is being checked. EDIT: It looks like that dladdr is not going to help me as it needs dlopen first.

Well you can’t (portably) avoid executing global constructors in the library that’s loaded. There might be some non-portable hacks to get back control before the constructors run, using library dependencies and the implementation-specific order in which constructors run to call _exit (doing all of this from a forked child process) from another library’s constructor beforehand, but I think that’s getting into far-fetched hack territory. Ideally dlopen would have a RTLD_NOEXEC flag to prevent any code execution in the library, useful for tasks like yours.

Читайте также:  Браузер командной строки linux

Yeah, that is wishful thinking. There is a RTLD_NOLOAD, but that just returns NULL when the library is not loaded before. I don’t think there is even a solution available that takes 32-bit/64-bit into account (without building a 32-bit and 64-bit program designed to check this, that is).

Well there’s another ugly hack — you could fork a child process and ptrace it, and terminate it on the first mmap system call made. The prior open call should give you the pathname. 🙂 By the way, why do you need to know the pathname? I suspect there’s a better way to do what you’re trying to achieve.

primus intercepts GL calls and splits rendering from accelerating. These libraries do not have to sit in $LD_LIBRARY_PATH , hence I cannot pass libGL.so.1 to the dlopen function in that program and therefore I have to pass the absolute path to the libraries. In a second program, I want to lookup the libraries as stated in the question so I can pass it to the the primus program.

For systems with GNU libc and Python the following is the closest I found. It uses LD_DEBUG (described in the man page of ld.so(8) ).

LD_DEBUG=libs python3 -c "import ctypes; ctypes.CDLL('libssl.so.1.0.0')" 2>&1 | \ grep -A 1000 "initialize program: python" | grep -A 3 "find library" 

The output (for libssl.so.1.0.0 ) is the following:

 15370: find library=libssl.so.1.0.0 [0]; searching 15370: search cache=/etc/ld.so.cache 15370: trying file=/lib/x86_64-linux-gnu/libssl.so.1.0.0 15370: 15370: find library=libcrypto.so.1.0.0 [0]; searching 15370: search cache=/etc/ld.so.cache 15370: trying file=/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 15370: 

I implemented such a script here:

#!/usr/bin/env python3 """ Like `type` but for libs. """ import sys import os from argparse import ArgumentParser from glob import glob def parse_ld_conf_file(fn): paths = [] for l in open(fn).read().splitlines(): l = l.strip() if not l: continue if l.startswith("#"): continue if l.startswith("include "): for sub_fn in glob(l[len("include "):]): paths.extend(parse_ld_conf_file(sub_fn)) continue paths.append(l) return paths def get_ld_paths(): # To be very correct, see man-page of ld.so. # And here: http://unix.stackexchange.com/questions/354295/what-is-the-default-value-of-ld-library-path/354296 # Short version, not specific to an executable, in this order: # - LD_LIBRARY_PATH # - /etc/ld.so.cache (instead we will parse /etc/ld.so.conf) # - /lib, /usr/lib (or maybe /lib64, /usr/lib64) paths = [] if "LD_LIBRARY_PATH" in os.environ: paths.extend(os.environ["LD_LIBRARY_PATH"].split(":")) paths.extend(parse_ld_conf_file("/etc/ld.so.conf")) paths.extend(["/lib", "/usr/lib", "/lib64", "/usr/lib64"]) return paths def main(): arg_parser = ArgumentParser() arg_parser.add_argument("lib") args = arg_parser.parse_args() paths = get_ld_paths() for p in paths: fn = "%s/%s" % (p, args.lib) if os.path.exists(fn): print(fn) return print("Did not found %r in %r." % (args.lib, paths), file=sys.stderr) sys.exit(1) if __name__ == "__main__": main() 

Источник

Ubuntu Linux Library Path

How do I determine the Ubuntu Linux Library Path? That is, how does the linker know where to got to grab the object files when linking my program?

Читайте также:  Localhost in linux mint

5 Answers 5

Look at /etc/ld.so.conf and the files in the /etc/ld.so.conf.d/ directory — that’s where it is set.

The file paths can be set explicitly when linking using the -L parameter, as well as the environment variable LD_LIBRARY_PATH .

There are also some paths hard-coded into the linker, using the -L param. You can see these with the command:

If it’s not a standard path ( /lib , /usr/lib ), you can specify the location with the compiler flag. For g++ , it’s -L/some/path/lib . If you use autotools, you can just configure with LDFLAGS=-L/some/path/lib if you need a specific path. If configure has been properly designed for the project, it should have a —with-some-library=PATH option, where you can also specify a path for that library only.

When linking, you need to specify the -L flag to indicate where the library is located. At runtime, the dynamic linker uses the paths given in «/etc/ld.so.conf», «/etc/ld.so.conf.d/*» and the value of LD_LIBRARY_PATH.

«sudo ldconfig» updates the system’s cache if you’ve just installed something new.

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Where does Ubuntu look for shared libraries?

When I run a process that links to a shared library at runtime (linked when the process starts, not linked later with dlload() ), where does it look for that shared library ( .so ) file other than LD_LIBRARY_PATH ? Background: I have some C++ code that I wrote that uses a particular third-party library. I have installed the library and compiled my code on two different platforms, both Ubuntu but different versions, and different versions of gcc as well. The library was compiled and installed from source, and is located in /usr/local/lib on both platforms. When I compile my code, I link with the pkg-config —libs parameters for the third-party library and I’ve verified that pkg-config —libs returns the exact same thing on both platforms. My code compiles successfully on both platforms, and LD_LIBRARY_PATH is not defined (or defined as empty: «» ) on both platforms. However, when I run it on one platoform it works fine, and on the other I get this error:

error while loading shared libraries: libthrift-0.9.0.so: cannot open shared object file: No such file or directory 

Funnily enough, the ones that doesn’t work is the newer version of Ubuntu and gcc. :/ So I’m trying to figure out how the working one is able to locate the library, so that I can make the broken one locate the library in the same way. (i.e., without setting LD_LIBRARY_PATH ) Update: Here’s my output from cat /etc/ld.so.conf.d/* . on the working (older) system:

/usr/lib/mesa /usr/lib32/mesa /usr/lib/alsa-lib # libc default configuration /usr/local/lib # Multiarch support /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu 
# libc default configuration /usr/local/lib # Multiarch support /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/mesa 

Источник

Читайте также:  Посмотреть версию дистрибутива linux

Finding the absolute path of shared libraries used by an executable

$ ldd /usr/sbin/lshw linux-vdso.so.1 => (0x00007fff8bdaf000) libresolv.so.2 => /lib64/libresolv.so.2 (0x000000360e400000) libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x0000003631600000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x000000360ec00000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000360d800000) libc.so.6 => /lib64/libc.so.6 (0x000000360c000000) libpthread.so.0 => /lib64/libpthread.so.0 (0x000000360cc00000) libdl.so.2 => /lib64/libdl.so.2 (0x000000360c800000) libm.so.6 => /lib64/libm.so.6 (0x000000360c400000) /lib64/ld-linux-x86-64.so.2 (0x000000360bc00000) 

If I want to find the absolute locations of the shared libraries (and want to exclude linux-vdso.so.1 for obvious reasons), how do I go about it? Using awk with regular expressions seems brittle here. ldd has a verbose flag (-v) which does print the complete paths of the shared libraries, but it is not very friendly for machine reading. Is there another way to go about this? If someone knows of a system call to do so, I am fine with that too. PS: For a bit of context, I want to run this program in chroot jail, so I need to make sure that the shared libraries are all available. Compiling it statically works without all this drama, but that is a path I am looking to avoid. Update: I think I may have found something which may be more suitable while reading Michael Kerrisk’s book, «The Linux Programming Interface». If I run a program as $ LD_DEBUG=libs lshw , it outputs various helpful information. For example:

$ LD_DEBUG=libs lshw 32058: find library=libresolv.so.2 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libresolv.so.2 32058: 32058: find library=libstdc++.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libstdc++.so.6 32058: 32058: find library=libgcc_s.so.1 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libgcc_s.so.1 32058: 32058: find library=libc.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libc.so.6 32058: 32058: find library=libm.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libm.so.6 32058: 32058: 32058: prelink checking: ok 32058: 32058: calling init: /lib64/ld-linux-x86-64.so.2 32058: 32058: 32058: calling init: /lib64/libc.so.6 32058: 32058: 32058: calling init: /lib64/libm.so.6 32058: 32058: 32058: calling init: /lib64/libgcc_s.so.1 32058: 32058: 32058: calling init: /lib64/libstdc++.so.6 32058: 32058: 32058: calling init: /lib64/libresolv.so.2

I think, if I look for the ‘calling init’ lines, I will have the shared library paths it is initializing before starting to execute the program.

Источник

Оцените статью
Adblock
detector