Android NDK


标签(空格分隔): 未分类 android ndk 文档



root@hwG620S-L01:/ # ps
ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     828    488   c01ff4bc 0001cb84 S /init
...
root      254   1     511572 8288  ffffffff 40106204 S zygote
...
u0_a142   24365 254   540088 25016 ffffffff 5bb22d20 t com.example.hellojni
...
u0_a142   24455 31190 748    464   c01ff4bc 000340f4 S lib/gdbserver
...
root      31190 1     6724   260   ffffffff 00024b9c S /sbin/adbd

重点关注com.example.hellojni和ib/gdbserver这两个进程的关系

  1. 两个进程是相同的用户u0_a142
  2. com.example.hellojni是由zygote创建的,gdbserver是由adbd创建的

ndk-gdbserver.png gdb的具体细节非root进程的gdbserver如何调试能调试其他进程?debug的关键系统调用ptrace。传送门这个细节有时会引起一个问题

[2015-01-05 11:11:40 - Substitute: ] --> [2015-01-05 11:11:40 - Substitute: ] [2015-01-05 11:11:40 - Substitute: ] --> [2015-01-05 11:11:40 - Substitute: ] D:\Android-ndk\samples\hello-jni/obj/local/armeabi/ [2015-01-05 14:46:32 - HelloJni] gdbserver output: [2015-01-05 14:46:32 - HelloJni] run-as: Package 'com.example.hellojni' has corrupt installation [2015-01-05 14:46:32 - HelloJni] Verify if the application was built with NDK_DEBUG=1 问题产生的原因是/data目录的others用户是不能有读写权限的,否则就会报该错细节,根因参见上面的传送门

上述调试模型存在的问题,应用是先启动之后adbserver进程才attach到被调试进程的,导致应用在一开始执行时断点是不生效的,这点在刚开始调试断点时需要特别注意。

debug版本和release版本的区别 Table 1. Results of NDKDEBUG (command line) and android:debuggable (manifest) combinations. |manifest\jni-Android.mk|NDKDEBUG=0|NDKDEBUG=1|NDKDEBUG not specified | | -------- | -----| ---- | |android:debuggble="true" |Debug; Symbols; Optimized1 | Debug; Symbols; Not optimized2 | (same as NDK_DEBUG=1) | |android:debuggable="false" |Release; Symbols; Optimized |Release; Symbols; Not optimized| Release; No symbols; Optimized*3 |

*1: Useful for profiling. *2: Default for running ndk-gdb. *3: Default mode. ndk-debug jni/Application.mk NDK_DEBUG=1 is the equivalent of APP_OPTIM= debug in Application.mk, and complies with the GCC -O0 option. NDK_DEBUG=0 is the equivalent of APP_OPTIM= release, and complies with GCC -O2. For more information about APP_OPTIM,


2、ndk的so文件的组成symbol strip的概念,debug和release版本的区别

2.1 gcc -g选项与 ld -rdynamic意义,调试信息的生成,如何读取,objdump readelf

  • symbol在生成的二进制文件中分为两种 (两个segment) symtab dynsym
  • symtab 的生成对应于gcc 的 -g选项
  • dynsym的生成对应于linker的 -rdynamic选项 参见
  • dynsym是symtab的一个子集

出现两个表的原因是有些历史的因素,参见 基本原因如下:调试的信息由于运行时时不需要的,所以可以从可执行的程序中strip掉,在loader加载可执行程序时也不会加载调试信息按照运行时是否加载二进制的文件中分为两部分allocablenon-allocable,allocable是在程序运行时加载到内存的,non-allocable是不需要加载到内存的,不是运行必须的toolchain中的strip程序就是去除二进制文件中的non-allocable的部分的(参见)完整的symtab包含了大量的debug数据linker和debugger使用,因为不需要加载到内存,这些在动态链接库出现之前一直运行的很好,很合理,动态链接库的出现带来了问题,动态链接库在运行时需要一部分non-allocable的信息,这是就面临了一些问题,要不把所有的symtab变为allocable,或者新建一个allocable的segment,显然新建一个symtab的子集仅仅包含动态链接所需的信息,更加有时间和空间和效率,这样dynsym segment就诞生了,dynsym是allocable的。

这些信息可以通过objdump 和readelf来获得

android系统log中堆栈的生成方式

debuggerd -b


Copyright © FengGuangtu 2017