【问题标题】:Zygote shared libraries handlingZygote 共享库处理
【发布时间】:2018-06-23 10:16:51
【问题描述】:

zygote如何处理android中的共享库? Zygote 是 Android 中的一个特殊进程,它处理每个新应用程序进程的分叉。这些进程只是普通的 Linux 进程。我们可以将 Zygote 视为设备上启动的每个应用程序和服务的模板进程。它由 Android 运行时启动,它还启动第一个虚拟机 (VM)。然后,VM 调用 Zygote 的 main() 方法,该方法使 Zygote 将所有共享的 Java 类和资源预加载到内存中。它如何与 shaed 库一起使用?

【问题讨论】:

    标签: android process


    【解决方案1】:

    有一次我在共享库编译时遇到问题,应用程序崩溃并显示以下跟踪日志:

    backtrace:
    #00 pc 00000000001938f8  /data/app/com.xxxxx.test-1/lib/arm64/libmyNative.so
    #01 pc 0000000000002300  /system/bin/linker64 (__dl__ZN6soinfo12CallFunctionEPKcPFvvE.part.22+80)
    #02 pc 000000000000294c  /system/bin/linker64 (__dl__ZN6soinfo9CallArrayEPKcPPFvvEmb+232)
    #03 pc 0000000000005200  /system/bin/linker64 (__dl__Z9do_dlopenPKciPK17android_dlextinfo+264)
    #04 pc 0000000000001cbc  /system/bin/linker64 (__dl__ZL10dlopen_extPKciPK17android_dlextinfo+48)
    #05 pc 0000000000284bc8  /system/lib64/libart.so (art::JavaVMExt::LoadNativeLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, art::Handle<art::mirror::ClassLoader>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)+824)
    #06 pc 00000000002c2e2c  /system/lib64/libart.so (art::Runtime_nativeLoad(_JNIEnv*, _jclass*, _jstring*, _jobject*, _jstring*)+700)
    #07 pc 00000000000b9528  /data/dalvik-cache/arm64/system@framework@boot.oat
    

    从日志中,我们可以了解到这个 libmyNative.so 是如何在第一时间被加载的。
    1. boot.oat 不仅负责加载android框架和资源,还负责加载应用程序共享库。
    2. boot.oat是一个Java库,它会调用native libart.so来加载native库,Runtime_nativeLoad() -> LoadNativeLibrary()。
    3.下面的步骤,如果你之前hook过native library,或者你之前自己从android application动态链接native library,你会更好的理解。自己链接共享库而不是调用 System.loadLibrary() 的一个例子:

    void* lib = dlopen("/data/app/com.xxxxx.test-1/lib/arm64/libmyNative.so", RTLD_LAZY);
    void* func_ptr = (void*)dlsym(* lib, "JNI_Onload");
    

    所以在 LoadNativeLibrary() 内部,它做了类似的事情。您可以从here 检查 LoadNativeLibrary() 的实现。

    1. 在本机库加载期间,还会执行部分初始化代码。如果你知道 .so 文件结构,你就会知道有一个 .init_array 部分,其中包括一些由编译器添加的初始化函数和你在代码中显式声明的全局构造函数。我遇到的崩溃是在编译器添加的 init 函数之一中。

    2. 我怀疑的一件事是在 LoadNativeLibrary() 内部,它似乎调用 JNI_Onload(),但据我观察,它没有。因为我试图让JNI_Onload() 直接返回 -1,所以它不会从那里抛出错误消息,而是在我调用 System.loadLibrary() 时抛出错误消息。这是意料之中的。

    03-08 18:10:12.311 14797-14797/com.xxxxx.test E/JNI_OnLoad: System.loadLibrary(myNative)

    java.lang.UnsatisfiedLinkError: JNI_ERR 从“/data/app/com.xxxxx.test-2/lib/arm64/libmyNative.so”中的 JNI_OnLoad 返回
    在 java.lang.Runtime.loadLibrary(Runtime.java:372)
    在 java.lang.System.loadLibrary(System.java:988)
    在 com.gemalto.tee.taadmin.TaAdmin.init(TaAdmin.java:86)

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 2018-03-18
      • 1970-01-01
      • 2012-10-11
      • 1970-01-01
      • 2019-10-06
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多