Android加载so出现dlopen failed: empty/missing DT_HASH in "libx.so" (built with --hash-style=gnu?)错误
2016-01-07 19:44
579 查看
在网上搜了一下,参考下面两个帖子:
http://stackoverflow.com/questions/28638809/android-ndk-unsatisfiedlinkerror-dlopen-failed-empty-missing-dt-hash http://blog.csdn.net/asmcvc/article/details/47659057
摘自第二个帖子的解决方法:
The library you are trying to load was most likely built with Wl,hash-style=gnu. This was not supported on Android until recently (afaik this isn't even in L). You need to build your libraries with -Wl,-hash-style=sysv.
How did you build cpplibrary.so? If you didn't do anything to manually switch to the gnu hash style, it could be a bug in the NDK.
One option is to add "LOCAL_LDFLAGS := -Wl,--hash-style=sysv" at screenrecord Android.mk though I am sure there is a less hacky method of doing so..
总结了一下是需要在Android.mk中添加链接选项:
LOCAL_LDFLAGS := Wl,-hash-style=sysv
libsysv-hash-table-library_ldflags := Wl,-hash-style=sysv
于是在修改前后查看了一下so节的变化:
readelf.exe -d libxxxx.so
readelf.exe -d libxxxx.so
上面用readelf来查看so的结构,两者是没有区别的,这个需要研究一下ELF的文件结构和其中各个段,在so的.dynamic段中需要通过一个tag来找到hash section,从而去索引编译的符号,这个tag在一般的Linux中是DT_GNU_HASH,而在Android中是DT_HASH,两者是不一样的。
上面提示的错误信息说DT_HASH找不到或者为空,并提示是不是编译的时候使用了--hash-style=gnu的编译选项,说明在用这个编译选项以后这个tag名字就是DT_GNU_HASH了,所以系统加载so的时候才会出错。
但是现在想不明白的是这个崩溃是偶现的,而且概率很低,按理说如果so格式有问题应该是必崩的才对,真正的原因还没搞明白。
http://stackoverflow.com/questions/28638809/android-ndk-unsatisfiedlinkerror-dlopen-failed-empty-missing-dt-hash http://blog.csdn.net/asmcvc/article/details/47659057
摘自第二个帖子的解决方法:
The library you are trying to load was most likely built with Wl,hash-style=gnu. This was not supported on Android until recently (afaik this isn't even in L). You need to build your libraries with -Wl,-hash-style=sysv.
How did you build cpplibrary.so? If you didn't do anything to manually switch to the gnu hash style, it could be a bug in the NDK.
One option is to add "LOCAL_LDFLAGS := -Wl,--hash-style=sysv" at screenrecord Android.mk though I am sure there is a less hacky method of doing so..
总结了一下是需要在Android.mk中添加链接选项:
LOCAL_LDFLAGS := Wl,-hash-style=sysv
libsysv-hash-table-library_ldflags := Wl,-hash-style=sysv
于是在修改前后查看了一下so节的变化:
readelf.exe -d libxxxx.so
Dynamic section at offset 0xed14 contains 27 entries: Tag Type Name/Value 0x00000003 (PLTGOT) 0xfee0 0x00000002 (PLTRELSZ) 552 (bytes) 0x00000017 (JMPREL) 0x46fc 0x00000014 (PLTREL) REL 0x00000011 (REL) 0x39c4 0x00000012 (RELSZ) 3384 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x6ffffffa (RELCOUNT) 420 0x00000006 (SYMTAB) 0x148 0x0000000b (SYMENT) 16 (bytes) 0x00000005 (STRTAB) 0x1918 0x0000000a (STRSZ) 5780 (bytes) 0x00000004 (HASH) 0x2fac 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x0000000e (SONAME) Library soname: [libbugrpt.so] 0x0000001a (FINI_ARRAY) 0xf590 0x0000001c (FINI_ARRAYSZ) 8 (bytes) 0x00000019 (INIT_ARRAY) 0xf598 0x0000001b (INIT_ARRAYSZ) 16 (bytes) 0x00000010 (SYMBOLIC) 0x0 0x0000001e (FLAGS) SYMBOLIC BIND_NOW 0x6ffffffb (FLAGS_1) Flags: NOW 0x00000000 (NULL) 0x0
readelf.exe -d libxxxx.so
Dynamic section at offset 0xed14 contains 27 entries: Tag Type Name/Value 0x00000003 (PLTGOT) 0xfee0 0x00000002 (PLTRELSZ) 552 (bytes) 0x00000017 (JMPREL) 0x46fc 0x00000014 (PLTREL) REL 0x00000011 (REL) 0x39c4 0x00000012 (RELSZ) 3384 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x6ffffffa (RELCOUNT) 420 0x00000006 (SYMTAB) 0x148 0x0000000b (SYMENT) 16 (bytes) 0x00000005 (STRTAB) 0x1918 0x0000000a (STRSZ) 5780 (bytes) 0x00000004 (HASH) 0x2fac 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x0000000e (SONAME) Library soname: [libbugrpt.so] 0x0000001a (FINI_ARRAY) 0xf590 0x0000001c (FINI_ARRAYSZ) 8 (bytes) 0x00000019 (INIT_ARRAY) 0xf598 0x0000001b (INIT_ARRAYSZ) 16 (bytes) 0x00000010 (SYMBOLIC) 0x0 0x0000001e (FLAGS) SYMBOLIC BIND_NOW 0x6ffffffb (FLAGS_1) Flags: NOW 0x00000000 (NULL) 0x0
上面用readelf来查看so的结构,两者是没有区别的,这个需要研究一下ELF的文件结构和其中各个段,在so的.dynamic段中需要通过一个tag来找到hash section,从而去索引编译的符号,这个tag在一般的Linux中是DT_GNU_HASH,而在Android中是DT_HASH,两者是不一样的。
上面提示的错误信息说DT_HASH找不到或者为空,并提示是不是编译的时候使用了--hash-style=gnu的编译选项,说明在用这个编译选项以后这个tag名字就是DT_GNU_HASH了,所以系统加载so的时候才会出错。
但是现在想不明白的是这个崩溃是偶现的,而且概率很低,按理说如果so格式有问题应该是必崩的才对,真正的原因还没搞明白。
相关文章推荐
- request获取路径的方式和区别
- [leetcode] 303. Range Sum Query - Immutable
- UI课程(图片动画/视图控制器/自定义视图/循环导入)
- UI课程(标签/文本输入框/图片/按钮/代理)
- UI布局(Layout)
- UIImageView 的 contentMode
- 蓝懿IOS学习之UITableView
- UITextFiled的LeftView
- 关于UITextView的几种回收键盘的方法
- 程序员面试问题1:数组问题 Programming Interview Questions 1: Array Pair Sum
- php生成UUID
- django实现用户登陆访问限制@login_required
- PV、UV、UIP、VV、CPC、CPM、RPM、CTR是什么意思?
- 使用druid连接池的超时回收机制排查连接泄露问题
- 样例问题 Example question for A4M33MPV course
- 出现could not build module foundation错误
- Android Stuido怎样查看快捷键冲突?
- java-对象的生命周期及AndroidUI卡顿
- easyui中方向键、tab键、回车键
- 既然有了点方法为啥还要用valueForKey