Android中类似Linux下ldd分析可执行文件和动态库对库的依赖

1. Android下面并没有Linux中的ldd工具,但是它也提供了一个类似的工具,路径如下:

prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-readelf

对的,就是arm-linux-androideabi-readelf这个工具
2.  如何使用:

[email protected]:/home/jon/code/V2_PRO# ./arm-linux-androideabi-readelf -d out/target/product/zqp1659_v2/symbols/system/bin/mm-qcamera-app 

Dynamic section at offset 0x14d64 contains 32 entries:
  Tag        Type                         Name/Value
 0x00000003 (PLTGOT)                     0x15f30
 0x00000002 (PLTRELSZ)                   392 (bytes)
 0x00000017 (JMPREL)                     0x10b8
 0x00000014 (PLTREL)                     REL
 0x00000011 (REL)                        0xba0
 0x00000012 (RELSZ)                      1304 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   158
 0x00000015 (DEBUG)                      0x0
 0x00000006 (SYMTAB)                     0x1a0
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000005 (STRTAB)                     0x6b0
 0x0000000a (STRSZ)                      946 (bytes)
 0x6ffffef5 (GNU_HASH)                   0xa64
 0x00000001 (NEEDED)                     Shared library: [libcutils.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libmmcamera_interface.so]
 0x00000001 (NEEDED)                     Shared library: [libc++.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000019 (INIT_ARRAY)                 0x15a28
 0x0000001b (INIT_ARRAYSZ)               12 (bytes)
 0x00000020 (PREINIT_ARRAY)              0x15a34
 0x00000021 (PREINIT_ARRAYSZ)            0x8
 0x0000001a (FINI_ARRAY)                 0x15a3c
 0x0000001c (FINI_ARRAYSZ)               8 (bytes)
 0x0000001e (FLAGS)                      BIND_NOW
 0x6ffffffb (FLAGS_1)                    Flags: NOW
 0x6ffffff0 (VERSYM)                     0xaac
 0x6ffffffe (VERNEED)                    0xb50
 0x6fffffff (VERNEEDNUM)                 2
 0x00000000 (NULL)                       0x0

如上可以分析出该可执行文件或者动态库对其他动态库的依赖

3.  分析Android的healthd进程无法打印堆栈的原因
首先分析healthd,这个可执行文件中是否含有打印堆栈需要的动态库

[email protected]:/home/jon/code/V2_PRO# ./arm-linux-androideabi-readelf -d out/target/product/zqp1659_v2/root/sbin/healthd 

There is no dynamic section in this file.

嗒嗒嗒,悲剧发生了,这个进程居然不含有任何的动态库,为什么呢
我们分析它的Android.mk文件
Android中类似Linux下ldd分析可执行文件和动态库对库的依赖
就是上图高亮的位置搞的鬼, LOCAL_FORCE_STATIC_EXECUTABLE将其标志该模块需要强制静态链接,从而导致加入的动态链接库失效。将其去除后再试下
Android中类似Linux下ldd分析可执行文件和动态库对库的依赖
编译之后,再看下其包含的动态库

[email protected]:/home/jon/code/V2_PRO# ./arm-linux-androideabi-readelf -d out/target/product/zqp1659_v2/root/sbin/healthd 

Dynamic section at offset 0x42a70 contains 32 entries:
  Tag        Type                         Name/Value
 0x00000003 (PLTGOT)                     0x43d68
 0x00000002 (PLTRELSZ)                   1304 (bytes)
 0x00000017 (JMPREL)                     0xa738
 0x00000014 (PLTREL)                     REL
 0x00000011 (REL)                        0x7110
 0x00000012 (RELSZ)                      13864 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   1553
 0x00000015 (DEBUG)                      0x0
 0x00000006 (SYMTAB)                     0x1c0
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000005 (STRTAB)                     0x25c0
 0x0000000a (STRSZ)                      15260 (bytes)
 0x6ffffef5 (GNU_HASH)                   0x615c
 0x00000001 (NEEDED)                     Shared library: [libutils.so]
 0x00000001 (NEEDED)                     Shared library: [libbacktrace.so]
 0x00000001 (NEEDED)                     Shared library: [libc++.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000020 (PREINIT_ARRAY)              0x41270
 0x00000021 (PREINIT_ARRAYSZ)            0x8
 0x00000019 (INIT_ARRAY)                 0x41278
 0x0000001b (INIT_ARRAYSZ)               56 (bytes)
 0x0000001a (FINI_ARRAY)                 0x412b0
 0x0000001c (FINI_ARRAYSZ)               8 (bytes)
 0x0000001e (FLAGS)                      BIND_NOW
 0x6ffffffb (FLAGS_1)                    Flags: NOW
 0x6ffffff0 (VERSYM)                     0x6c40
 0x6ffffffe (VERNEED)                    0x70c0
 0x6fffffff (VERNEEDNUM)                 2
 0x00000000 (NULL)                       0x0

OK,现在可以打印堆栈了