Self-compiled dalvik doesn't load shared libraries

7

I'm trying to run some Android code on VM in AWS. I've compiled Android from source and when I'm trying to load a library explicitly (using System.load) in dalvik vm I see following log:

android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!

Class that generates this error:

public class Server {
  private static final int port = 8080;

  public static void main(String[] args) throws Exception {
      System.load("libandroid_runtime.so");
      WebServer webServer = new WebServer(port);

      XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();

      PropertyHandlerMapping phm = new PropertyHandlerMapping();
      phm.addHandler("ImgCat", ImgCat.class);
      xmlRpcServer.setHandlerMapping(phm);

      XmlRpcServerConfigImpl serverConfig =
          (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
      serverConfig.setEnabledForExtensions(true);
      serverConfig.setContentLengthOptional(false);

      webServer.start();
  }
  }

Script I use to run programs in dalvikvm:

#!/bin/sh
base=/opt/android
root=$base/out/host/linux-x86
export ANDROID_ROOT=$root
bootpath=$root/framework
export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath  /framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar
export LD_LIBRARY_PATH=$root/lib:$LD_LIBRARY_PATH
export ANDROID_DATA=/tmp/dalvik_$USER
mkdir -p $ANDROID_DATA/dalvik-cache
echo $LD_LIBRARY_PATH
exec dalvikvm $@

Dalvikvm is executable from /out/host/linux-x86, not target. I think it may be a problem, but dalvikvm from target is not executable (file command). I've found somewhere that compiling Android with sim target will give me what I need, but I couldn't found branch where sim target is present.

Do you have any idea how to fix issue with loading shared libraries? Or maybe know which Android branch has sim target in lunch command?

Edit:

One more thing I found is that if I run my app using WithFramework it loads some libraries and then segfaults.

Edit2:

I've noticed that there may be a problem with libdl and libc. Libc depends on libdl what is diffrent than on my host linux. I've checked with readelf command:

readelf -d /home/ubuntu/android-x86/out/target/product/generic_x86/system/lib/libc.so 

Dynamic section at offset 0x72c54 contains 21 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libc.so]
 0x00000019 (INIT_ARRAY)                 0x727dc

Libdl does not depend on anything:

readelf -d /home/ubuntu/android-x86/out/target/product/generic_x86/system/lib/libdl.so 

Dynamic section at offset 0x658 contains 19 entries:
  Tag        Type                         Name/Value
 0x0000000e (SONAME)                     Library soname: [libdl.so]
 0x00000019 (INIT_ARRAY)                 0x1640

But there are some symbols undefined:

nm -D /home/ubuntu/android-x86/out/target/product/generic_x86/system/lib/libdl.so 
0000164c T __FINI_ARRAY__
00001640 T __INIT_ARRAY__
0000173c A __bss_start
         U __cxa_atexit
         U __cxa_finalize
         w __deregister_frame_info_bases
         w __register_frame_info_bases
         U __stack_chk_fail
0000173c A _edata
00001758 A _end
00000520 T dl_iterate_phdr
00000500 T dladdr
00000510 T dlclose
000004e0 T dlerror
000004d0 T dlopen
000004f0 T dlsym

Any idea how to fix it? (Do I need to fix it?)

android
shared-libraries
dalvik
android-x86
asked on Stack Overflow May 25, 2015 by Wojciech Reszelewski • edited May 31, 2015 by Wojciech Reszelewski

1 Answer

0

I found the location in dalvik vm where this error is thrown from. It looks like the following :

     if (javaLdLibraryPath != NULL) {
    ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath);
    if (ldLibraryPath.c_str() == NULL) {
      return NULL;
    }
    void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH");
    if (sym != NULL) {
      typedef void (*Fn)(const char*);
      Fn android_update_LD_LIBRARY_PATH = reinterpret_cast<Fn>(sym);
      (*android_update_LD_LIBRARY_PATH)(ldLibraryPath.c_str());
    } else {
      LOG(ERROR) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!";
    }
  }

It looks like if sym == null then you get that error message.

So I'm wondering if the previous line (see next code snipper) indicates simply that your android_update_LD_LIBRARY_PATH is initialized imcorrectly.

void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH");

Does this help?

found the code at: original source

answered on Stack Overflow Jun 3, 2015 by raddevus

User contributions licensed under CC BY-SA 3.0