dlopen fails only on arm64

437 views
Skip to first unread message

jim.b...@couchbase.com

unread,
Sep 1, 2021, 1:23:22 AM9/1/21
to android-ndk
I am trying to narrow down a problem that I am having that seems to be specific to arm64.  I've tried x86 and armv7 and they both function as you'd expect, on various API levels but the moment it comes to arm64 it's suddenly "library not found". 

It is a simple call to `dlopen(/data/data/<package name>/lib/<libname>.so, RTLD_NOW)` but I have no idea how to diagnose what is happening.  I've deconstructed the APK and found all 4 architectures present and valid but yet it simply will not load.  The dependencies are all permitted system libraries as well (liblog.so, libdl.so, libm.so, libc.so).  How can I diagnose and/or fix this?

jim.b...@couchbase.com

unread,
Sep 1, 2021, 1:40:29 AM9/1/21
to android-ndk
FYI in the time between posting this and it being approved I found some other topics similar to this.  It turns out I've had some wool pulled over my eyes by the Android emulator.  It seems to do what it wants in this regard which is why I was misled to believe that API version didn't matter.  I had tried this on 3 devices and 2 emulators:

armv7 API 22 - good
armv7 API 23 - good
armv8 API 25 - bad
x86 API 22 - good
x86 API 30 - good

It looks like the bad actor is arm64 but it's actually the dlopen change that happened in API24 where you are now supposed to call dlopen solely with the name of the library.  However, this breaks previous versions like 22 which require what the later versions strictly prohibit (ugh...).  So I have to resort to a try / fallback approach (first try the library name on its own and then if that fails try the full path).

Dan Albert

unread,
Sep 1, 2021, 4:33:47 AM9/1/21
to android-ndk
> However, this breaks previous versions like 22

That's what the samples do, and those work fine even on Jelly Bean. There's something else going on.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/c4ff1d3c-f0b3-4a74-b8e9-5895cb312479n%40googlegroups.com.

enh

unread,
Sep 1, 2021, 1:56:51 PM9/1/21
to android-ndk
On Wed, Sep 1, 2021 at 1:33 AM 'Dan Albert' via android-ndk <andro...@googlegroups.com> wrote:
> However, this breaks previous versions like 22

That's what the samples do, and those work fine even on Jelly Bean. There's something else going on.

well, depending on what they called their library/libraries, they might be hitting the flip side of that same bug they're talking about that we fixed in API 23: https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#correct-soname_path-handling-available-in-api-level-23

"""
API level 23 is the first release where search by soname is implemented. Earlier releases would assume that the basename of the library was the soname, and used that to search for already-loaded libraries. For example, dlopen("/this/directory/does/not/exist/libc.so", RTLD_NOW) would find /system/lib/libc.so because it’s already loaded. This also meant that it was impossible to have two libraries "dir1/libx.so" and "dir2/libx.so" --- the dynamic linker couldn’t tell the difference and would always use whichever was loaded first, even if you explicitly tried to load both. This also applied to DT_NEEDED entries.
"""

(this is one reason why i always recommend calling your library something like libcom.mycompany.myproduct.so :-) )

((and even if that doesn't turn on a lightbulb over your head, it's probably worth reading the rest of the document for what should be the canonical list of all significant behavior differences in the dynamic linker since jellybean...))
 

jim.b...@couchbase.com

unread,
Sep 1, 2021, 3:38:38 PM9/1/21
to android-ndk
Interesting that it is supposed to work.  Opening by name fails on API 22 for both Nexus 4 emulator and LGE Nexus 5 stock API 22 device.  Both return null.  Both succeed with the full path (as does an LGE Nexus 5 stock API 23 device that I cannot confirm if that name works or not).  The reverse is true for two separate arm64 API 25 devices:  Samsung SM-G950U1 and Elo Touch msm8953 in that by name succeeds and by path fails. 

In case it wasn't clear, this is a library that I build myself using the NDK and then bundle inside an app.  I am not calling dlopen directly on a system library. 

enh

unread,
Sep 1, 2021, 4:27:53 PM9/1/21
to android-ndk
what's the name, and what's the path? (and what are the DT_NEEDEDs?)

jim.b...@couchbase.com

unread,
Sep 1, 2021, 7:27:29 PM9/1/21
to android-ndk
The name is libcblite.so (filename and SO_NAME are the same).  The DT_NEEDED are what I mentioned above ( liblog.so, libdl.so, libm.so, libc.so ).  My workaround appears to be functioning everywhere I need it to (try the name, fallback to the path).
Reply all
Reply to author
Forward
0 new messages