我正在使用崩溃报告服务跟踪我们的Android应用程序(使用NDK加载C ++库)的崩溃。少数用户遇到以下崩溃:
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "cpplibrary.so" (built with --hash-style=gnu?)
at java.lang.Runtime.loadLibrary(Runtime.java:365)
at java.lang.System.loadLibrary(System.java:526)
我可以在互联网上找到的这个错误提及(例如这个Google Groups post)讨论了构建lib的问题,这会导致每次运行应用程序时都会出现此错误。几乎没有关于为什么偶尔会发生这种情况的信息。 This post是我能找到的最接近的。
根据崩溃痕迹,看起来任何特定的用户都会经历这种不断的延伸;我不确定这些用户是否能够正确加载lib。有没有人对有时可能导致这种情况发生的想法有所了解?我可以以不同的方式进行NDK构建以试图阻止它吗?
谢谢!
编辑:This post提到了两种有条件地获取此类错误的方法;我会照顾他们。
Edit2:构建文件: Android.mk(摘录):
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_C_INCLUDES := <Source Path>...
LOCAL_CFLAGS := -DANDROID -Wall
LOCAL_CPPFLAGS := -DENABLE_SDK_DEBUGGING=1 -DENABLE_SDK_LOGGING=1
LOCAL_MODULE := cpplibrary
LOCAL_SRC_FILES := <Source Files> / ...
LOCAL_LDLIBS := -llog -landroid
LOCAL_STATIC_LIBRARIES := cpplibrary
include $(BUILD_SHARED_LIBRARY)
Application.mk:
APP_STL := stlport_static
APP_CFLAGS += -std=c++11
答案 0 :(得分:3)
您尝试加载的库很可能是使用-Wl,--hash-style=gnu
构建的。 Android直到最近才支持此功能(即使在L中也不支持)。您需要使用-Wl,--hash-style=sysv
构建库。
你是如何建立cpplibrary.so
的?如果您没有做任何事情来手动切换到gnu哈希样式,那么它可能是NDK中的一个错误。
答案 1 :(得分:1)
如果您是第三方建筑.so库供他人使用,则设置-Wl,--hash-style=both
似乎是最好的主意。这使您可以更快地加载Gnu样式的哈希值和SysV哈希值的向后兼容性。
答案 2 :(得分:1)
--hash-style=both
应该可以工作。选中https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#gnu-hashes-availible-in-api-level-23作为参考。
答案 3 :(得分:1)
我在使用Android Cmake时遇到了这个问题,并且已经设置
-DANDROID_PLATFORM=23
根据{{3}},GNU哈希样式可从API 23获得,并且由于ANDROID_PLATFORM
设置为23,因此标记--hash-style=gnu
被自动设置。
我已经通过降低-DANDROID_PLATFORM=21
来解决此问题,然后将该标志设置为标志--hash-style=both
答案 4 :(得分:0)
这可能是由于目标设备的不同构造造成的。您是否能够从崩溃报告中收集设备供应商/型号信息? 不确定,但我猜你需要在多个拱门(armeabi,armeabi-v7,neon)中编译本地库,以克服这种不可能性。
答案 5 :(得分:0)
要查看它是否是哈希样式问题,您可以运行readelf -d cpplibrary.so并查找GNU_HASH部分。如果有一个--hash-style = sysv应该解决问题。
答案 6 :(得分:0)
尽管出于这个问题,我在Android Studio导入第三方so文件中遇到了这个问题。最终,我发现这是因为Gradle自动剥离了产品的“ so”文件,因此禁用此选项即可。
android {
........
packagingOptions{
doNotStrip "*/armeabi-v7a/*.so"
}
.......
}
答案 7 :(得分:0)
如果有人使用 this project template 为 Flutter 构建 Rust 库,将 makefile
中的相应行更改为 ANDROID_ARMV7_LINKER=$(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/$(OS_NAME)-x86_64/bin/armv7a-linux-androideabi22-clang
会有所帮助。