How to change the library include path of a binary from bash?

9.1k views Asked by At

I have a software properly installed on Kubuntu.

Now, I am patching and testing some of its libraries.

How can I start the software from bash so that it loads my patched libraries instead of the official libs?

e.g.:
the official libs are locate in /usr/lib/
my patch libraries (used during test development) are in /home/user/dev/lib/

I tried:

$ set LD_LIBRARY_PATH=/home/user/dev/lib/  
$ binary_app &

but to no avail.

I'd prefer a solution that can be set from the bash, but if it's not possible, I could also modify the cmake file of this C++ software.

The aim is to allow me to easily start the application either with the vanilla libs, or with my patched libs to see the differences.

Edit: it's a KDE .so file

The library I am testing is a KDE4 library. The official lib is in /usr/lib/kde4/ . In that directory, none of the library start with the lib prefix.

Whether I do:

/lib/ld-linux-x86-64.so.2 --list  --library-path PATH EXEC  

or

ldd EXEC  

The library is not listed at all.

On the other hand, if if move the original library away from /usr/lib/kde4/, the application starts but the corresponding functionality is missing.

Are KDE4 libraries loaded in a specific way? Maybe the variable to set is different...

Edit 2

All the answers are good and useful... unfortunately, it turned out that the problem does not appear to be related to the lib path setting. I'm dealing with a plugin architecture and the .so loading path appears to be hard-coded somewhere in the application. I need to spend more time within the source code to understand what's happening... Thanks and +1 to all.

5

There are 5 answers

2
Jan de Vos On BEST ANSWER

From 'man bash':

When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell.

[....]

ยท shell variables and functions marked for export, along with variables exported for the command, passed in the environment

You need to 'export' a variable if it is to be seen by programs you execute.

However, you can also try the following:

/lib/ld-linux.so.2 --library-path PATH EXECUTABLE

See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

2
Karl Bielefeldt On

Try export LD_LIBRARY_PATH=... instead of set.

1
AudioBubble On

Isn't you app setuid or setgid by chance? In this case LD_LIBRARY_PATH will be ignored.

0
KitsuneYMG On

Put everything on one line:

LD_LIBRARY_PATH=foo binary_app&
1
rve On

I already put this in a comment but after thinking about it I think the best way to do this (using a different library just for testing/debugging) is using LD_PRELOAD, see What is the LD_PRELOAD trick?

From the man page:

LD_PRELOAD

A whitespace-separated list of additional, user-specified, ELF shared libraries to be loaded before all others. This can be used to selectively override functions in other shared libraries. For set-user-ID/set-group-ID ELF binaries, only libraries in the standard search directories that are also set-user-ID will be loaded.

Update:

After the updated question it seems the application is using dlopen to open the library using a absolute path. I don't think you can do anything about it. See man dlopen

Update2:

Maybe there is something you can do: you might be able to LD_PRELOAD your own dlopen function which modifies the path to your own library...