Libxxx.so has text relocations问题的解决方法

编程入门 行业动态 更新时间:2024-10-21 23:15:10

Libxxx.so has text relocations问题的<a href=https://www.elefans.com/category/jswz/34/1770089.html style=解决方法"/>

Libxxx.so has text relocations问题的解决方法

问题表现形式

当targetSdkVersion >= 23且使用debug签名时,在Android 6.0+的Android设备上运行App会直接挂死,并输出以下错误Log:
E/linker: /data/app/packagename/lib/arm/libxxx.so: has text relocations
W/System.err: java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/packagename/lib/arm/libxxx.so: has text relocations

当targetSdkVersion<23且使用debug签名时,在Android 6.0+的Android设备上虽然运行正常,但会输出以下警告Log:
W/linker: “/data/app/packagename/lib/arm/libxxx.so”: has W+E (writable and executable) load segments. This is a security risk shared libraries with W+E load segments will not be supported in a future Android release. Please fix the library.
W/linker: /data/app/packagename/lib/arm/libxxx.so has text relocations. This is wasting memory and prevents security hardening. Please fix.

App启动时弹出提醒对话框
targetSdkVersion < 23且使用debug签名的APK运行在高版本系统上(此处使用Android 7.0 测试),每次启动时会弹出一个对话框,其内容如下:
Detected problems with app native libraries (please consult log for detail) : libxxx.so: text relocations
上述各种表象可以发现是同一个问题所致,即libxxx.so: has text relocations
经过测试发现,打release 包没有问题,debug包不行 。最后比对debug和release 环境的不同点发现了原因。debuggable这个才是是否出现弹框的关键, 即使你使用debug 签名,只要关闭了debuggable 模式 都不会出现弹框;
下面来说一下设置debuggable 开启 关闭的方法:
在APP的build.gradle里面设置debuggable = true 或者 false;

问题原因

网上查找了各种资料,发现有篇博客说的非常详细,下面贴出博客地址:
在Android 6.0官方的更新说明中有提及“libxxx.so: text relocations”这个问题:
On previous versions of Android, if your app requested the system to load a shared library with text relocations, the system displayed a warning but still allowed the library to be loaded. Beginning in this release, the system rejects this library if your app’s target SDK version is 23 or higher. To help you detect if a library failed to load, your app should log the dlopen(3) failure, and include the problem description text that the dlerror(3) call returns. To learn more about handling text relocations, see this guide.
这个问题在6.0之前只会产生一个警告,系统还是可以正常加载包含text relocations的共享库的,但从6.0起,即SDK Version>=23时,系统将会拒绝加载包含text relocations的共享库,同时输出错误Log,也就是上文中看到的错误日志。其实引起该问题的最根本原因,是so动态链接库的代码并非PIC(Position independent code),关于PIC的概念可以参考维基百科的介绍。在Android 6.0更新说明中,也只是简单提了一句处理方案:To learn more about handling text relocations, see this guide.

解决方案

当你在网上搜索此问题时,会发现90%以上的搜索结果都告诉你把targetSdkVersion设为小于23。诚然,这样是可以回避掉上述问题,但只是治标不治本,并非终极方案。如果App想使用6.0甚至7.0的新特性(前几天Android O开发者预览版已发布,此问题更是刻不容缓),就必须将targetSdkVersion提高至23或以上,所以这个问题必须彻底解决,决不能采用targetSdkVersion设为小于23的妥协方案。真正的解决方案就是解决so动态链接库中的*text relocations (TEXTRELs)*问题。

解决TEXTRELs问题大部分会建议在使用NDK编译so时配置Android.mk,增添PIC相关的配置项,这样编译出来的so文件将不再有text relocations的问题,具体配置为 LOCAL_LDFLAGS += -fPIC
当动态库链接的开源库引用了一些使用了绝对地址的汇编文件时,这个配置项并不能生成与代码位置无关的动态库,此时在Linux上使用命令 readelf -a Libxxx.so | grep TEXTREL,会发现打印

TEXTREL 表示代码段重定位表地址,PIC 的共享对象不会包含任何代码段重定位表。因此如果上述命令有此类输出输出,则该表示so文件存在此类问题。

网上大部分资料到这一步就已经结束了,下面介绍一个工具来定位是哪些汇编文件引入的

最终解决方案

Scanelf
该命令的官方说明文档链接:
-q, --quiet Only output ‘bad’ things.
-T, --textrels Locate cause of TEXTRELs
我们可以通过 scanelf -qT libxxx.so此时会打印出libxxx.so是哪些符号引起的,这些符号就是具体某一函数;

x264_opencl_precalculate_frame_cost 是x264开源库里面的一个函数
WebRtcAecm_ResetAdaptiveChannelNeon 是WebRTC回声处理的一个模块
这两个开源库在应用中并没有使用到,所以可以在编译选项中关闭这两个模块;
至于 SKP_Silk_sigm_Q15 这个是必须要用到的,只能网上找新版本的开源代码替换升级;
经过几个小时努力,完美解决;

更多推荐

Libxxx.so has text relocations问题的解决方法

本文发布于:2024-03-08 05:32:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1719949.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:解决方法   Libxxx   text   relocations

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!