dlopen and LD_LIBRARY_PATH woes

239 views
Skip to first unread message

Grégory Pakosz

unread,
Dec 4, 2014, 1:05:04 PM12/4/14
to andro...@googlegroups.com
Hello,

I noticed the following behavior:
- when I copy libFoo.so to /system/lib/
- and try dlopen("libFoo.so");
- dlopen() returns NULL and dlerror() returns NULL as well.
- while dlopen("/system/lib/libFoo.so"); works

Is it expected?

When I add log traces, e.g. __android_log_print(ANDROID_LOG_INFO, "XXX", "LD_LIBRARY_PATH = %s", getenv("LD_LIBRARY_PATH")); I get:
09-12 13:32:23.719: I/XXX(26155): LD_LIBRARY_PATH = /vendor/lib:/system/lib

A quick glimpse at bionic's linker/linker.c doesn't seem to reveal soinfo *find_library(const char* name) actually tries to prepend name with any path.


Regards,
Gregory

Grégory Pakosz

unread,
Dec 5, 2014, 6:13:59 AM12/5/14
to andro...@googlegroups.com
I take back what I said about "A quick glimpse at bionic's linker/linker.c doesn't seem to reveal soinfo *find_library(const char* name) actually tries to prepend name with any path."

The following fragment from linker/linker.cpp lines 861-865 seems to indicate bionic's linker tries to prepend name with paths:

  int fd = open_library_on_path(name, g_ld_library_paths);
  if (fd == -1) {
    fd = open_library_on_path(name, kDefaultLdPaths);
  }
  return fd;


Yet, I'm unable to dlopen("libFoo.so") despite /system/lib/libFoo.so being there. dlopen() fails and dlerror() returns NULL.

Gregory

Ilya Konstantinov

unread,
Dec 16, 2014, 10:44:05 AM12/16/14
to andro...@googlegroups.com
Hi Grégory,

On Friday, December 5, 2014 1:13:59 PM UTC+2, Grégory Pakosz wrote:
Yet, I'm unable to dlopen("libFoo.so") despite /system/lib/libFoo.so being there. dlopen() fails and dlerror() returns NULL.

I'm just shooting in the dark here. Starting from Jellybean, this issue is solved:

The fix implemented custom API to reconfigure the library paths mid-run. Changing the LD_LIBRARY_PATH mid-run has no effect since at this point it's already parsed. Moreover, if your code is running from within a Java app, the Android code (see usage of java.lang.Runtime.nativeLoad) might've modified the library paths, so getenv("LD_LIBRARY_PATH") is no longer indicative. Inspect the calls to nativeLoad to see what it actually does.

If you're running a standalone binary (i.e. built with $(BUILD_EXECUTABLE)), then unless you do something funny, it *will* use the LD_LIBRARY_PATH.
Reply all
Reply to author
Forward
0 new messages