-
Notifications
You must be signed in to change notification settings - Fork 257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shared library symbols not visible on dlopen()? #201
Comments
tl;dr; This one of the not many differences between linux loader and android loader. On Android only the main executable and LD_PRELOADs are considered to be RTLD_GLOBAL, all the dependencies of the main executable remain RTLD_LOCAL. Longer explanation: ld-linux.so marks everything linked against main executable with RTLD_GLOBAL, this is why the example works on Linux. Android loader was not handling RTLD_GLOBAL correctly up until M release. It was fixed in M for things like dlopen/dlsym() but not for the dependencies of the main executable, because it lead to many compatibility problems. Workaround: Adding libshared.so dependency to libplugin.so should solve this problem and make the executable. |
@dimitry- Thanks a lot for the information! I guess this issue can be closed here as it's not an NDK issue. |
The pgsql extension uses pcre functions but does not link against libpcre by default, as the php executable which dlopen():s the extension already links against libpcre. However, on Android this doesn't work, see android/ndk#201 so we need to link against libpcre explicitly.
The pgsql extension uses pcre functions but does not link against libpcre by default, as the php executable which dlopen():s the extension already links against libpcre. However, on Android this doesn't work, see android/ndk#201 so we need to link against libpcre explicitly.
Summary: On some Android device, there is libv8.so in system ROM. E.g. /system/lib/libv8.so or /vendor/lib/libv8.so On old Android, dlopen() with RTLD_GLOBAL is not handled well and it's by default RTLD_LOCAL. Even we call System.loadLibrary("v8") before, during the time RNV8 call System.loadLibrary("v8executor") and search libv8.so in DT_NEEDED. It seems bionic linker will use system libv8.so instead of ours. Since our libv8.so is customized with libplatform.so, this leads to unresolved symbol as Kudo/react-native-v8#29. That's why I am proposing to rename libv8.so as libv8android.so and to prevent name conflict from system libv8.so. Reference for RTLD_GLOBAL: android/ndk#201
Summary: On some Android device, there is libv8.so in system ROM. E.g. /system/lib/libv8.so or /vendor/lib/libv8.so On old Android, dlopen() with RTLD_GLOBAL is not handled well and it's by default RTLD_LOCAL. Even we call System.loadLibrary("v8") before, during the time RNV8 call System.loadLibrary("v8executor") and search libv8.so in DT_NEEDED. It seems bionic linker will use system libv8.so instead of ours. Since our libv8.so is customized with libplatform.so, this leads to unresolved symbol as #29. That's why I am proposing to rename libv8.so as libv8android.so and to prevent name conflict from system libv8.so. Reference for RTLD_GLOBAL: android/ndk#201
Summary: On some Android device, there is libv8.so in system ROM. E.g. /system/lib/libv8.so or /vendor/lib/libv8.so On old Android, dlopen() with RTLD_GLOBAL is not handled well and it's by default RTLD_LOCAL. Even we call System.loadLibrary("v8") before, during the time RNV8 call System.loadLibrary("v8executor") and search libv8.so in DT_NEEDED. It seems bionic linker will use system libv8.so instead of ours. Since our libv8.so is customized with libplatform.so, this leads to unresolved symbol as #29. That's why I am proposing to rename libv8.so as libv8android.so and to prevent name conflict from system libv8.so. Reference for RTLD_GLOBAL: android/ndk#201
Summary: On some Android device, there is libv8.so in system ROM. E.g. /system/lib/libv8.so or /vendor/lib/libv8.so On old Android, dlopen() with RTLD_GLOBAL is not handled well and it's by default RTLD_LOCAL. Even we call System.loadLibrary("v8") before, during the time RNV8 call System.loadLibrary("v8executor") and search libv8.so in DT_NEEDED. It seems bionic linker will use system libv8.so instead of ours. Since our libv8.so is customized with libplatform.so, this leads to unresolved symbol as #29. That's why I am proposing to rename libv8.so as libv8android.so and to prevent name conflict from system libv8.so. Reference for RTLD_GLOBAL: android/ndk#201 (cherry picked from commit 5a78dd5)
Summary: On some Android device, there is libv8.so in system ROM. E.g. /system/lib/libv8.so or /vendor/lib/libv8.so On old Android, dlopen() with RTLD_GLOBAL is not handled well and it's by default RTLD_LOCAL. Even we call System.loadLibrary("v8") before, during the time RNV8 call System.loadLibrary("v8executor") and search libv8.so in DT_NEEDED. It seems bionic linker will use system libv8.so instead of ours. Since our libv8.so is customized with libplatform.so, this leads to unresolved symbol as #29. That's why I am proposing to rename libv8.so as libv8android.so and to prevent name conflict from system libv8.so. Reference for RTLD_GLOBAL: android/ndk#201 (cherry picked from commit 5a78dd5)
I get some error |
as described in android/ndk#201.
Android requires shared modules that use symbols from other shared modules to be linked before they can be dlopen()ed in the correct order. Not doing so leads to a missing symbol error: android/ndk#201 We need to always allow linking for this. Also add a soname, although it's not confirmed that it's needed, and it doesn't really hurt if it isn't needed.
Android requires shared modules that use symbols from other shared modules to be linked before they can be dlopen()ed in the correct order. Not doing so leads to a missing symbol error: android/ndk#201 We need to always allow linking for this. Also add a soname, although it's not confirmed that it's needed, and it doesn't really hurt if it isn't needed.
Android requires shared modules that use symbols from other shared modules to be linked before they can be dlopen()ed in the correct order. Not doing so leads to a missing symbol error: android/ndk#201 We need to always allow linking for this. Also add a soname, although it's not confirmed that it's needed, and it doesn't really hurt if it isn't needed.
I have a shared library
libshared.so
containing a functionlibshared_get_value()
.I also have a shared library
libplugin.so
, which does not link againstlibshared.so
but references the extern functionlibshared_get_value()
Finally there is an executable linking against
libshared.so
. At runtime this executable tries todlopen()
thelibplugin.so
shared library.This works on "normal" Linux (tested on Ubuntu 16.04).
This does not work on Android (tested on Android 5.0/arm and 6.0/aarch) but fails at runtime with the error message
cannot locate symbol "libshared_get_value" referenced by "libplugin.so"
.This difference in behaviour causes problems for things like perl and node, where extensions built as shared libraries expects symbols from already loaded libraries to be visible without needing to link against the libraries containing the symbols explicitly. See e.g. How To Link -lperl to Extensions During Build where the following is said:
Is the Android linker (or tools) really broken in this regard, or is the behaviour the expected/desired one?
See https://github.com/termux/shared-library-testcase for a small test case.
The text was updated successfully, but these errors were encountered: