【Android】System分区应用自带库与原生库同名问题分析
System分区应用自带库与原生库同名问题分析
问题背景
某系统应用发生必现崩溃问题。崩溃log如下
0*-** **:**:**.** 66666 66666 E ***** aar error:: java.lang.UnsatisfiedLinkError: dlopen failed: cannot
locate symbol "_TTT_TTT_TTT"
referenced by "/system/app/LINDUO/lib/arm64/liblinduo.so"...
0*-** **:**:**.** 66666 66666 E offline_da aar error:: at java.lang.Runtime.loadLibrary0(Runtime.java)
- 根据Log提示,动态库依赖时找不到_TTT_TTT_TTT这个符号。检索liblinduo.so依赖的动态库。发现,_TTT_TTT_TTT这个符号,在应用自带的libA.so这个库中。
nm -D linA.so | grep _TTT_TTT_TTT
- 检查进程对应的map文件,/proc/66666/maps,发现加载了系统中的libA.so(/system/lib64/libA.so)。
相关知识点
动态库加载优先级
- 应用私有目录
- 自定义注入路径
- 系统目录
- Android 7.0+强制/system分区的应用使用AOSP原生库,即使应用自带同名库也会被忽略。可以理解为,Aosp的原生库比如libA.so是Aosp自身依赖的。如果系统应用自带了libA.so,那么system分区的应用,就会忽略这个库。因为,不能让应用自带的库把系统的原生库替换了。
解决System分区应用自带库与原生库同名问题
- 把应用挪到/vendor分区,或者作为后装应用(可以的话),利用Android命名空间机制隔离(参考Asop官网原生库的命名空间)
- 重命名应用自带的动态库,把动态库改成其他名字。
- 使用和系统版本统一的动态库。
- 应用使用静态库,静态依赖。