49

我正在 Nexus 5 上测试 Android 6.0,我正在使用 Metaio(我知道该服务将于 12 月 15 日结束,但在那一天我们将转移到另一个 AR 平台)。问题是当我启动 ARActivity 时出现以下错误:

    09-02 08:45:11.138: E/AndroidRuntime(6141):     java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/com.myapp.myapp/lib/arm/libavcodec.so: has text relocations
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at java.lang.Runtime.loadLibrary(Runtime.java:372)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at java.lang.System.loadLibrary(System.java:1076)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at com.metaio.sdk.jni.IMetaioSDKAndroid.loadNativeLibs(IMetaioSDKAndroid.java:54)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at metaioCloudPlugin.SplashActivity.loadNativeLibs(SplashActivity.java:37)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at metaioCloudPlugin.SplashActivity.onCreate(SplashActivity.java:68)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.Activity.performCreate(Activity.java:6237)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.ActivityThread.-wrap11(ActivityThread.java)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.os.Handler.dispatchMessage(Handler.java:102)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.os.Looper.loop(Looper.java:148)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at android.app.ActivityThread.main(ActivityThread.java:5417)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at java.lang.reflect.Method.invoke(Native Method)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    09-02 08:45:11.138: E/AndroidRuntime(6141):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

有谁知道可能的解决方案或至少是一种解决方法?我正在努力寻找解决方案,但我无法理解问题可能是什么。

4

6 回答 6

47

今天,在 Nexus 6(摩托罗拉)上使用 Android 6.0 测试我的应用时,我收到了相同的错误消息。我通过检查清单文件中的 targetSDKVersion 解决了我的问题。使用“22”而不是“23”作为 targetSDKVersion 解决了它。(见下文)

<uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="22" />

我还检查了 build.gradle 文件的编译版本和 targetSDKversion:

compileSdkVersion 22
    buildToolsVersion '22.0.1'

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 22
    }

希望这会帮助你。然而,这只是一个短期的解决方法,我希望我们能从 metaio 那里得到一些反馈。

问候,克里斯汀

于 2015-09-02T20:46:00.110 回答
15

您可以通过执行以下操作检查您的共享图书馆是否有文本重定位:

readelf -a path/to/yourlib.so | grep TEXTREL

如果它有文本重定位,它会显示如下内容:

0x00000016 (TEXTREL)                    0x0

如果是这种情况,您可以使用可用的最新 NDK 版本重新编译您的共享库:

ndk-build -B -j 8

如果再次检查,grep 命令将不会返回任何内容。

于 2015-12-27T19:16:30.727 回答
12

如果要求加载带有文本重定位的共享库,以前版本的 Android 会发出警告:

“libfoo.so 有文本重定位。这会浪费内存并阻止安全强化。请修复。”。

尽管如此,操作系统还是会加载库。如果您的应用程序的目标 SDK 版本 >= 23,Marshmallow 将拒绝库。系统不再记录此内容,因为它假定您的应用程序将自己记录 dlopen(3) 失败,并包含来自 dlerror(3) 的文本,它确实解释了问题。不幸的是,在这种情况下,许多应用程序似乎捕获并隐藏了UnsatisfiedLinkError throw by System.loadLibrary它,在您尝试调用您的本机方法之一并且 VM 抱怨它不存在之前,通常不会留下库无法加载的线索。

您可以使用命令行 scanelf 工具来检查文本重定位。您可以在互联网上找到有关该主题的建议;例如https://wiki.gentoo.org/wiki/Hardened/Textrels_Guide是一个有用的指南。

于 2015-09-30T19:11:30.337 回答
12

好的,即使设置了 targetSDK 23,我也可以在这里工作。

对于我和我的分支来说,需要修补的五个文件是

libavcodec\arm\fft_fixed_neon.S  
libavcodec\arm\fft_neon.S  
libavcodec\arm\fft_vfp.S   
libavcodec\arm\mlpdsp_armv5te.S  
libutil\arm\asm.S  

我从https://github.com/FFmpeg/FFmpeg获取了最新的

您还需要在构建中的某处声明 HAVE_SECTION_DATA_REL_RO 以供 asm.S 中的宏使用动态重定位选项。

于 2015-10-16T01:39:55.567 回答
6

经过长时间的挣扎和尝试以不同的方式编译FFmpeg,我找到了解决方案。确保使用 --disable-asm 标志编译 FFmpeg。这将确保 FFmpeg 在针对 Android M (SDK 23) 进行编译时不会发生文本重定位并且不会崩溃

为了确保它有效,您可以使用上面提到的 readelf。

干杯

于 2016-03-04T10:32:40.873 回答
2

我收到了来自 metaio 的 SDK 团队的反馈。他们说这个问题不能通过 metaio 轻易解决,因为它与 FFMpeg 库有关。我们不得不希望 FFMpeg 的更新能够解决这个问题。我假设我们必须等待这样的更新并在应用程序中交换库文件。

我还没有寻找 FFMpeg 开发人员联系论坛来进行查询或通知错误。不小心认识一个?

最好的毕业生,克里斯汀

于 2015-09-16T13:27:41.960 回答