java - android加载库失败

标签 java android c android-ndk java-native-interface

当我使用System.loadLibrary()加载我的so文件时,很少会失败并且Logcat显示

Cannot load library: reloc_library[1286]: 121 cannot locate '__cxa_atexit'
java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1285]:   169 cannot locate '__cxa_atexit'...
at java.lang.Runtime.loadLibrary(Runtime.java:370)
at java.lang.System.loadLibrary(System.java:535)

在网上搜索后,没有找到任何相关信息

cannot locate '__cxa_atexit'

(尤其是关键字 __cxa_atexit)。为什么找不到这个功能呢?这个函数好像在libc.so中。我的 native 代码中不使用 C++,仅使用 C。我的 NDK 版本是 android-ndk-r10e。我认为“无法找到 __cxa_atexit”可能是一个相对线索。

大多数情况下(也许数十亿次应用程序启动),它可以正常工作,但很少像上面那样崩溃。换句话说,我无法让它在我的测试手机上崩溃,但是,它在某些用户的手机上很少崩溃。

此问题可能与 another problem 相同.

更新

发生此崩溃的大多数手机是 android 4.0.3 和 android 4.0.4。这两个版本都是API-15。

更新

在阅读了一些Android的源代码后,我发现这个问题可能与dlopen有关。错误消息“无法加载库:reloc_library...”来自运行时被劫持的函数 dlopen。跟踪是 runtime dlopen -> find_library -> init_library -> link_image -> reloc_library。

也许当它解析我的so文件中的符号时,它发现“__cxa_atexit”未定义。然后它在加载的符号中查找,但什么也没找到。 (为什么找不到__cxa_atexit?)最后运行到第1285行,代码为:

DL_ERR("%5d cannot locate '%s'...\n", pid, sym_name);

我对链接器一无所知。谁能解释或猜测为什么无法找到 __cxa_atexit ?这是Android的一个bug吗?

更新

它在所有 Android 版本上都会崩溃,而不仅仅是 4.0.3 和 4.0.4。

4.0.3 和 4.0.4 上的错误消息是

java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1286]: 121 cannot locate '__cxa_atexit'

如上所述。

在4.0.3和4.0.4上加载其他一些so时,它是

cannot locate 'strcpy'

4.2.2 上的错误消息是

java.lang.UnsatisfiedLinkError: Cannot load library: load_library(linker.cpp:767): can't read file /mnt/asec/app-name-1/lib/libname.so: I/O error

最佳答案

首先,请确保您调用了 System.loadLibrary(),如下所示:

public class MainActivity extends Activity {
    static {
        System.loadLibrary("main")
    }
    ...
}

然后根据the second answer in this post , 问题在于一些静态加载到 native 库中的外部依赖项。它们仅卡在 Android 4.0 上,并且在 4.2 及更高版本上运行良好。因此您应该检查您的 so 文件。

我只是把他的答案放在这里:

如果遇到问题,请将 __android_log_print 放入库的 JNI_onLoad 中(如果有的话)。如果没有被调用,请检查所有可以静态调用的函数(注意,有些函数可能隐藏在宏后面)并尝试删除它们以查看是否能够加载库

关于java - android加载库失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32860294/

相关文章:

android - 如何阻止/取消阻止android中的所有来电/去电/短信?

android - (Android)如何显示图像的一部分?

c++ - 如何获得显示器序列号?

java - Java中根据3个自定义字符串对ArrayList进行排序

android - 从固件更改标准 Android 应用程序中的资源

java - Java 列表中的二分查找

使用DevC++编译错误 "Error stray '\24 0' in program"

c - 将指针的地址分配给指针到指针

java - 正则表达式前瞻和后视 : followed by this or that

java - CXF 服务器端记录到表