Unable to dlopen(libTest.so): Cannot load library: link_image[1995]: failed to link libTest.so

1,198 views
Skip to first unread message

pps

unread,
Mar 20, 2013, 5:21:07 PM3/20/13
to andro...@googlegroups.com
Internet is full of that error, unfortunately, I'm unable to find anything that could help me solve the problem.

First of all, there is no problem with my code or the way I load the library: it works fine except one phone. I suspect that there is a required symbol in some library is missing but I have clue whatsoever how to do that task with android. I pulled all libs that my libTest.so requires. What tool can I use to be able to find what symbol is missing?

here's the logcat that I get:
D/dalvikvm( 6100): Trying to load lib /data/data/com.test/lib/libTestAbc.so 0x49d39608
I/dalvikvm( 6100): Unable to dlopen(/data/data/com.test/lib/libTestAbc.so): Cannot load library: link_image[1995]: failed to link libTestAbc.so
I/dalvikvm( 6100):
W/System.err( 6100): java.lang.UnsatisfiedLinkError: Library TestAbc not found
W/System.err( 6100):     at java.lang.Runtime.loadLibrary(Runtime.java:461)
...

Any suggestion on how to resolve the error?

Thanks

David Turner

unread,
Mar 20, 2013, 5:27:48 PM3/20/13
to andro...@googlegroups.com
Do you know which version of the system is running on this problematic phone? Also, which make/model?


--
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 post to this group, send email to andro...@googlegroups.com.
Visit this group at http://groups.google.com/group/android-ndk?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

pps

unread,
Mar 20, 2013, 7:45:15 PM3/20/13
to andro...@googlegroups.com
It's SAMSUNG-SGH-I997
samsung/SGH-I997/SGH-I997:2.2.1/FROYO/UCKD5:user/release-keys

CODENAME: REL
INCREMENTAL: UCKD5
RELEASE: 2.2.1
SDK: 8

This is an AT&T samsung infuse. By the way, in the past the app was tested and worked fine on this phone, now it does not load.

All I need is to have some sort of log showing why it cannot load it. There is an strace on the phone, but it's kind of complicated to update the app to sleep and start strace to monitor it. There should be an easy way to re-parse dependencies (something like depends32 on win32)

pps

unread,
Mar 20, 2013, 8:11:18 PM3/20/13
to andro...@googlegroups.com
Ok, I figured it out.

add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml

When I compiled with APP_PLATFORM=android-8 I got a link error for pthread_setname_np

I removed reference to this function and now my app loads fine.
What's the best way to access the function "dynamically". On Win32 I'd LoadLibrary and GetProcAddr. I don't want to do that on Android since location of pthread functions might change in the future.

Can I add some "weak" symbol attribute so that locally defined function would be used if not overridden by any linked shared object? Is there such concept on Android/Linux? If there is no such way, what's the best way to find out dynamically if this function is available and use it?

Jeffrey Walton

unread,
Mar 20, 2013, 8:34:56 PM3/20/13
to andro...@googlegroups.com
On Wed, Mar 20, 2013 at 8:11 PM, pps <pavlov...@gmail.com> wrote:
> Ok, I figured it out.
>
> add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is
> larger than android:minSdkVersion 8 in ./AndroidManifest.xml
>
> When I compiled with APP_PLATFORM=android-8 I got a link error for
> pthread_setname_np
>
> I removed reference to this function and now my app loads fine.
> What's the best way to access the function "dynamically". On Win32 I'd
> LoadLibrary and GetProcAddr. I don't want to do that on Android since
> location of pthread functions might change in the future.
The *nix equivalent is dlopen and dlsym (more below).

> Can I add some "weak" symbol attribute so that locally defined function
> would be used if not overridden by any linked shared object? Is there such
> concept on Android/Linux?
Yes. See the weak attribute at
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.

> If there is no such way, what's the best way to
> find out dynamically if this function is available and use it?
dlopen and dlsym. See, for example, linux.die.net/man/3/dlopen. Before
accepting failure, try both RTLD_NOW and RTLD_LAZY. Different
platforms respond differently to the flags.

Also be careful of RTLD_GLOBAL, which might affect the "One Definition
Rule" (ODR).

Jeff

pps

unread,
Mar 20, 2013, 9:41:41 PM3/20/13
to andro...@googlegroups.com, nolo...@gmail.com
On Wednesday, March 20, 2013 8:34:56 PM UTC-4, Jeffrey Walton wrote:
On Wed, Mar 20, 2013 at 8:11 PM, pps <pavlov...@gmail.com> wrote:
> Ok, I figured it out.
>
> add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is
> larger than android:minSdkVersion 8 in ./AndroidManifest.xml
>
> When I compiled with APP_PLATFORM=android-8 I got a link error for
> pthread_setname_np
>
> I removed reference to this function and now my app loads fine.
> What's the best way to access the function "dynamically". On Win32 I'd
> LoadLibrary and GetProcAddr. I don't want to do that on Android since
> location of pthread functions might change in the future.
The *nix equivalent is dlopen and dlsym (more below).


I know about dlopen/dlsym, the issue is that I don't know where is that pthread_setname_np defined.
Today, on most androids it's in libc.so I suppose, tomorrow it might be pthread.so. I had an android device that had libc.so.6 and pthread.so; basically, dlopen isn't the best idea in this case.
 
> Can I add some "weak" symbol attribute so that locally defined function
> would be used if not overridden by any linked shared object? Is there such
> concept on Android/Linux?
Yes. See the weak attribute at
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.

Yep, that works. GCC has weak externals for Win32 that behave the way I described. The weak symbol on ELFs is either 0 or imported (e.g. I cannot define my alternative implementation).



Back to the original question: what's the best way to find unresolved external symbol? I pulled all shared objects from target device, what tool I can use that could tell me that symbol XYZ isn't defined anywhere? Is there such tool that works on Windows, or, can I find that using utils from the NDK?
 

Jeffrey Walton

unread,
Mar 21, 2013, 1:07:35 AM3/21/13
to pps, andro...@googlegroups.com
On Wed, Mar 20, 2013 at 9:41 PM, pps <pavlov...@gmail.com> wrote:
> ...
>
> Back to the original question: what's the best way to find unresolved
> external symbol? I pulled all shared objects from target device, what tool I
> can use that could tell me that symbol XYZ isn't defined anywhere? Is there
> such tool that works on Windows, or, can I find that using utils from the
> NDK?
http://stackoverflow.com/questions/3340170/depends-exe-for-gnu-linux

Jeff

pps

unread,
Mar 21, 2013, 1:14:57 AM3/21/13
to andro...@googlegroups.com, pps, nolo...@gmail.com
I thought that I had mentioned "ldd for android" in the title, but it appears that I didn't :)
ldd does not exist for android (what a weirdo broken linux is this Android?!)
Perhaps, if I were using Linux, then ldd on linux is able to do this task. Does it also say if a symbol isn't resolved, or it only shows which modules are missing?

 

Tor Lillqvist

unread,
Mar 21, 2013, 3:36:53 AM3/21/13
to andro...@googlegroups.com, pps
ldd does not exist for android (what a weirdo broken linux is this Android?!)
 
Android uses the Linux kernel. Period. It is not, and is not claimed to be, otherwise "Linux". Live with it.

--tml
 

David Turner

unread,
Mar 21, 2013, 6:43:29 AM3/21/13
to andro...@googlegroups.com
On Thu, Mar 21, 2013 at 2:41 AM, pps <pavlov...@gmail.com> wrote:
On Wednesday, March 20, 2013 8:34:56 PM UTC-4, Jeffrey Walton wrote:
On Wed, Mar 20, 2013 at 8:11 PM, pps <pavlov...@gmail.com> wrote:
> Ok, I figured it out.
>
> add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is
> larger than android:minSdkVersion 8 in ./AndroidManifest.xml
>
> When I compiled with APP_PLATFORM=android-8 I got a link error for
> pthread_setname_np
>
> I removed reference to this function and now my app loads fine.
> What's the best way to access the function "dynamically". On Win32 I'd
> LoadLibrary and GetProcAddr. I don't want to do that on Android since
> location of pthread functions might change in the future.
The *nix equivalent is dlopen and dlsym (more below).


I know about dlopen/dlsym, the issue is that I don't know where is that pthread_setname_np defined.
Today, on most androids it's in libc.so I suppose, tomorrow it might be pthread.so. I had an android device that had libc.so.6 and pthread.so; basically, dlopen isn't the best idea in this case.

On Android, it will always be libc.so. There is no way future versions of the platform will break the ABI on purpose, this is not GNU/Linux :-)

 
> Can I add some "weak" symbol attribute so that locally defined function
> would be used if not overridden by any linked shared object? Is there such
> concept on Android/Linux?
Yes. See the weak attribute at
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.

Yep, that works. GCC has weak externals for Win32 that behave the way I described. The weak symbol on ELFs is either 0 or imported (e.g. I cannot define my alternative implementation).

weak symbols might not be properly handled by the Froyo dynamic linker. IIRC, support was only added later. I'd suggest keeping using dlopen()/dlsym() is you're targetting anything older than Gingerbread.


Back to the original question: what's the best way to find unresolved external symbol? I pulled all shared objects from target device, what tool I can use that could tell me that symbol XYZ isn't defined anywhere? Is there such tool that works on Windows, or, can I find that using utils from the NDK?
 
On more recent versions of the platform, the dynamic linker will tell you in logcat which symbol is actually missing.

You can also list the symbols exported by an ARM shared library with "arm-linux-androideabi-nm --defined-only /path/to/libfoo.so", this can be useful to look at the content of $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/lib/

Use "--undefined-only" instead of "--defined-only" to see which symbols your own library depends on.

If you have an Android source tree checkout, $ANDROID/development/ndk/platforms/android-$PLATFORM/arch-$ARCH/symbols/ contains various text files listing the exact public symbols exported by the NDK for each system library.

pps

unread,
Mar 21, 2013, 4:48:22 PM3/21/13
to andro...@googlegroups.com


On Thursday, March 21, 2013 6:43:29 AM UTC-4, Digit wrote:


On Thu, Mar 21, 2013 at 2:41 AM, pps <pavlov...@gmail.com> wrote:
On Wednesday, March 20, 2013 8:34:56 PM UTC-4, Jeffrey Walton wrote:
On Wed, Mar 20, 2013 at 8:11 PM, pps <pavlov...@gmail.com> wrote:
> Ok, I figured it out.
>
> add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is
> larger than android:minSdkVersion 8 in ./AndroidManifest.xml
>
> When I compiled with APP_PLATFORM=android-8 I got a link error for
> pthread_setname_np
>
> I removed reference to this function and now my app loads fine.
> What's the best way to access the function "dynamically". On Win32 I'd
> LoadLibrary and GetProcAddr. I don't want to do that on Android since
> location of pthread functions might change in the future.
The *nix equivalent is dlopen and dlsym (more below).


I know about dlopen/dlsym, the issue is that I don't know where is that pthread_setname_np defined.
Today, on most androids it's in libc.so I suppose, tomorrow it might be pthread.so. I had an android device that had libc.so.6 and pthread.so; basically, dlopen isn't the best idea in this case.

On Android, it will always be libc.so. There is no way future versions of the platform will break the ABI on purpose, this is not GNU/Linux :-)


At some point I had to work on an Android based tv or stb and it was different. It had pthreads.so (libpthread or whatever regular name on linux).

 
 
> Can I add some "weak" symbol attribute so that locally defined function
> would be used if not overridden by any linked shared object? Is there such
> concept on Android/Linux?
Yes. See the weak attribute at
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.

Yep, that works. GCC has weak externals for Win32 that behave the way I described. The weak symbol on ELFs is either 0 or imported (e.g. I cannot define my alternative implementation).

weak symbols might not be properly handled by the Froyo dynamic linker. IIRC, support was only added later. I'd suggest keeping using dlopen()/dlsym() is you're targetting anything older than Gingerbread.


Back to the original question: what's the best way to find unresolved external symbol? I pulled all shared objects from target device, what tool I can use that could tell me that symbol XYZ isn't defined anywhere? Is there such tool that works on Windows, or, can I find that using utils from the NDK?
 
On more recent versions of the platform, the dynamic linker will tell you in logcat which symbol is actually missing.

Yes, i saw that. Because of some problem with gold linker the app doesn't load on latest JB devices. If I -fuse-ld=bfd then it loads ok.
 

You can also list the symbols exported by an ARM shared library with "arm-linux-androideabi-nm --defined-only /path/to/libfoo.so", this can be useful to look at the content of $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/lib/

Use "--undefined-only" instead of "--defined-only" to see which symbols your own library depends on.

If you have an Android source tree checkout, $ANDROID/development/ndk/platforms/android-$PLATFORM/arch-$ARCH/symbols/ contains various text files listing the exact public symbols exported by the NDK for each system library.


Are you saying that nm will load libfoo.so and other libraries that libfoo.so requires? If not, then it's quite useless.
I know how to list symbols and, theoretically, I could then see what symbol does not exist in any of the libraries present on the phone (I did it once sorting them all then comparing lists of names with araxis and removing matching names). This task of iterating over all required symbols and checking if they are exported by any of linked in objects is best done by computers and that's what I'm asking. Very often that loading issue was related to some gcc internal symbols that aren't exported for some reason here and there and it's difficult to go over all these obscure __fsdvsi style names.

some newer androids do show what's the missing symbol name, but sometimes (like in this case now) mobiles that do have that newer android also do not have loading issues. So, I really need a tool that does that. I recall, that more than a year I had it (probable it was from some elftools or some library and I think i was able to do what need on windows, but I absolutely don't remember how I did it back then).




depends.exe on windows tell right away if a symbol or a dll is missing and I'd like ot know a tool that does the same shit

David Turner

unread,
Mar 21, 2013, 5:03:26 PM3/21/13
to andro...@googlegroups.com
On Thu, Mar 21, 2013 at 9:48 PM, pps <pavlov...@gmail.com> wrote:
On Android, it will always be libc.so. There is no way future versions of the platform will break the ABI on purpose, this is not GNU/Linux :-)


At some point I had to work on an Android based tv or stb and it was different. It had pthreads.so (libpthread or whatever regular name on linux).

Some "Android-based" devices do all kind of weird stuff, and they're definitely not compatible. You should not expect to use the official SDK/NDK tools to write apps for them. No idea what they provide for development though.

There is also the special case of GoogleTV. For historical reasons, they have a GLibc-based userland, which is why they cannot support NDK-based applications. Hopefully they'll fix this in a future revision of the platform, but frankly I don't know much.

Apart from that, the NDK official ABIs are carefully maintained to ensure they never break existing applications.

Are you saying that nm will load libfoo.so and other libraries that libfoo.so requires? If not, then it's quite useless.
I know how to list symbols and, theoretically, I could then see what symbol does not exist in any of the libraries present on the phone (I did it once sorting them all then comparing lists of names with araxis and removing matching names). This task of iterating over all required symbols and checking if they are exported by any of linked in objects is best done by computers and that's what I'm asking. Very often that loading issue was related to some gcc internal symbols that aren't exported for some reason here and there and it's difficult to go over all these obscure __fsdvsi style names.
 
some newer androids do show what's the missing symbol name, but sometimes (like in this case now) mobiles that do have that newer android also do not have loading issues. So, I really need a tool that does that. I recall, that more than a year I had it (probable it was from some elftools or some library and I think i was able to do what need on windows, but I absolutely don't remember how I did it back then).


No, nm will just dump the symbols for a given binary. You're looking for the equivalent of the "ldd" Linux command, except that there isn't one right now. Writing a Python script to do what you need shouldn't be too difficult though. May I ask you to file a feature request on b.android.com about something like that.

Note that the problem with GCC symbols you're experiencing shouldn't happen if you're using ndk-build, which takes care of it. In a nutshell, when generating binaries with a custom build system, you should always ensure that -lgcc is explicitely placed, on the final link command line, _after_ any other object or static libraries, and _before_ any shared libraries. 

Hope this helps.


pps

unread,
Mar 21, 2013, 6:47:49 PM3/21/13
to andro...@googlegroups.com
On Thursday, March 21, 2013 5:03:26 PM UTC-4, Digit wrote:


On Thu, Mar 21, 2013 at 9:48 PM, pps <pavlov...@gmail.com> wrote:
On Android, it will always be libc.so. There is no way future versions of the platform will break the ABI on purpose, this is not GNU/Linux :-)


At some point I had to work on an Android based tv or stb and it was different. It had pthreads.so (libpthread or whatever regular name on linux).

Some "Android-based" devices do all kind of weird stuff, and they're definitely not compatible. You should not expect to use the official SDK/NDK tools to write apps for them. No idea what they provide for development though.

There is also the special case of GoogleTV. For historical reasons, they have a GLibc-based userland, which is why they cannot support NDK-based applications. Hopefully they'll fix this in a future revision of the platform, but frankly I don't know much.

Apart from that, the NDK official ABIs are carefully maintained to ensure they never break existing applications.

We use official NDK, but my app links to 3rd party prebuilt shared and static libs that were build by some older ndk or perhaps some other tool. So, sometimes it's difficult to resolve that kind of issues. I can definitely say, that at our office we spent more than 1-2weeks or human hours fixing that same error: building with certain NDK would breake builds on certain android builds. Eventually, we figured out: if something doesn't load we try multiple devices, but at the beginning it was a nightmare of guessing with the binutils and "parsing" symbol list with a magnifying glass. If you track NDK changes, some of them mention some internal gcc symbols were included/removed etc. I definitely hit these errors, and when I saw updates mentioning these fixes I saw these errors disappear. In fact, latest jelly bean mentions that incorrectly exported exidx (or something like that) was removed, but it breaks builds compiled with r8d if gold was used for linking and unwinder facility was used (I'm waiting for the fix, meanwhile, we have to wait half an hour every time bfd does it's job).
 

David Turner

unread,
Mar 21, 2013, 7:12:43 PM3/21/13
to andro...@googlegroups.com
On Thu, Mar 21, 2013 at 11:47 PM, pps <pavlov...@gmail.com> wrote:
w these errors disappear. In fact, latest jelly bean mentions that incorrectly exported exidx (or something like that) was removed, but it breaks builds compiled with r8d if gold was used for linking and unwinder facility was used (I'm waiting for the fix, meanwhile, we have to wait half an hour every time bfd does it's job).
 
It's your lucky day! NDK r8e just got released with the fix: http://developer.android.com/tools/sdk/ndk/index.html

pps

unread,
Mar 23, 2013, 12:19:11 AM3/23/13
to andro...@googlegroups.com

First 10 seconds and it looks that it's more broken that any other NDK so far. AFAIR r8c or r8b would always rebuild. Now, after I clean and try to build it does whole nothing.
Seems like ndk-build clean does not work, that's why building after cleaning doesn't compile anything.

Steven Combs

unread,
Aug 23, 2013, 9:42:36 PM8/23/13
to andro...@googlegroups.com
I know this is a few months old but I was curious what the fix was for this. I saw your post on another thread about adding the following linker flags but I can't find in my build tree where to put it. I have searched quite a bit. 

I am working on a custom android build and some of the apps that reference the NDK dlopen aren't able to load symbols from their .so files. During my search I came across this article and your other one. Any advice? 

This is the article and here is the flag you had referenced at that time.
LOCAL_LDLIBS += -fuse-ld=bfd

I greatly appreciate it,
Thanks!
Reply all
Reply to author
Forward
0 new messages