【发布时间】:2015-12-27 21:31:47
【问题描述】:
当我使用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 中。我在本机代码中不使用 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 ?是安卓的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 上加载其他的时候,它是
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()”。如果失败,我将从apk中解压缩一个so文件,然后重新加载它。大多数时候,它可以正常工作,但有时会崩溃。换句话说,我不能让它在我自己的手机上崩溃,但是,它会在使用我的应用程序的其他用户上崩溃。
-
@KishuDroid 他们不是类似的问题。我的应用可以在大多数手机上正常运行,不会出现其他错误和崩溃。
-
我从来没有遇到过这个问题,但是很有可能某些4.0.x设备上的native loader不够稳定。当库的 armeabi 和 armeabi-v7a 变体都可用时,该加载程序中的一个错误自欺欺人。无论如何,一种解决方法是在 System.loadLibrary("main") 周围添加
try … catch并重试。另一种治疗方法 - 在 main. 之前显式调用 System.loadLibrary("c")
标签: java android c android-ndk java-native-interface