Android平台实现开机调试system_process
2014-07-25 15:57
309 查看
from:http://blog.csdn.net/i2cbus/article/details/21476401
1 首先要理清一下什么是system_process
1.1 system_process是我们在DDMS可以看到的名称。设置的地方在ActivityThread.java:
来自CODE的代码片
ActivityThread.java
1.2 system_process不是进程的名称,它是DDM用于区别不同的Java App的标识,对于一般Android程序来说会被设置成包名
1.3 system_process的进程名称是system_server,就是我们通过ps可以看到的
1.4 system_server进程是zygote进程孵化的第一个Java进程
1.5 zygote进程的程序名称叫app_process。
它的代码在frameworks\base\cmds\app_process\app_main.cpp
在init.rc中可以看到它是怎样启动起来的:
来自CODE的代码片
init.rc
1.6 system_server的启动过程如下:
在app_main.cpp的main函数中,有如下的代码:
来自CODE的代码片
app_main.cpp
runtime.start在正常情况下不会返回
在frameworks\base\core\java\com\android\internal\os\ZygoteInit.java的main中:
来自CODE的代码片
ZygoteInit.java
startSystemServer中:
来自CODE的代码片
startSystemServer.java
args中,有:--nice-name=system_server,这就是进程名system_server的由来
2 接下来我们来看看怎么去调试这个Android里Java层的最重要的进程,一般调试和开机调试
3 一般调试:
3.1 这种调试方法就是在Android启动完后,用adb连接Android,再调试system_process进程,实现起来是比较简单的,
3.2 无非就是在eclipse里创建一个名叫system_process的Android程序,然后在DDMS里选择system_process即可开始调试。
4 开机调试
4.1 有时我们需要调试一下system_process的初始化过程,因为上面的方法是在system_process已经初始化完之后开始调试的,用上面的方法是无能为力的,这就得另想办法。
4.2 搜索了下网络,没有找到比较实用的资源,于是自己研究了下。
4.3 其实也不是很麻烦:
找到SystemServer.java里的main函数,在函数的最开始加上几行代码:
来自CODE的代码片
SysemServer.java
4.4 解析下:
首先通过判断/system/debug是否存在来判断是否要等待调试器连接
android.os.Debug.waitForDebugger()就是等待调试器来连接,在调试器连接上之前代码不会往下执行
但是第一行代码就比较费解了,先来解析下什么叫ddm,ddm就是Dalvik Debug Monitor的缩写
android.ddm.DdmHandleAppName.setAppName就是要设置Java App在ddm里的名称。
如果不设置的话,你在DDMS里看到的Name一栏就会有一个“?”,这个时候,eclipse找不到对应的工程,所以就没法调试了。
所以这一行代码很重要
4.5 接下来就是重新编译代码并烧录了,这个看自己使用的是什么平台。
4.6 呵呵,是不是可以开机后用adb连接,再通过eclipse调试了?
5 这种方式的唯一缺陷就是要修改源代码,这个留着以后再研究,现在要做的是好好享受一下这种调试方法。
1 首先要理清一下什么是system_process
1.1 system_process是我们在DDMS可以看到的名称。设置的地方在ActivityThread.java:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> <a target=_blank id="L4" href="http://blog.csdn.net/i2cbus/article/details/21476401#L4" rel="#L4"> 4</a> <a target=_blank id="L5" href="http://blog.csdn.net/i2cbus/article/details/21476401#L5" rel="#L5"> 5</a> <a target=_blank id="L6" href="http://blog.csdn.net/i2cbus/article/details/21476401#L6" rel="#L6"> 6</a> <a target=_blank id="L7" href="http://blog.csdn.net/i2cbus/article/details/21476401#L7" rel="#L7"> 7</a> <a target=_blank id="L8" href="http://blog.csdn.net/i2cbus/article/details/21476401#L8" rel="#L8"> 8</a> <a target=_blank id="L9" href="http://blog.csdn.net/i2cbus/article/details/21476401#L9" rel="#L9"> 9</a> <a target=_blank id="L10" href="http://blog.csdn.net/i2cbus/article/details/21476401#L10" rel="#L10"> 10</a> <a target=_blank id="L11" href="http://blog.csdn.net/i2cbus/article/details/21476401#L11" rel="#L11"> 11</a> <a target=_blank id="L12" href="http://blog.csdn.net/i2cbus/article/details/21476401#L12" rel="#L12"> 12</a> <a target=_blank id="L13" href="http://blog.csdn.net/i2cbus/article/details/21476401#L13" rel="#L13"> 13</a> <a target=_blank id="L14" href="http://blog.csdn.net/i2cbus/article/details/21476401#L14" rel="#L14"> 14</a> | private void attach(boolean system) { sThreadLocal.set(this); mSystemThread = system; if (!system) { ... } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); ... } ... } |
ActivityThread.java
1.2 system_process不是进程的名称,它是DDM用于区别不同的Java App的标识,对于一般Android程序来说会被设置成包名
1.3 system_process的进程名称是system_server,就是我们通过ps可以看到的
1.4 system_server进程是zygote进程孵化的第一个Java进程
1.5 zygote进程的程序名称叫app_process。
它的代码在frameworks\base\cmds\app_process\app_main.cpp
在init.rc中可以看到它是怎样启动起来的:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> <a target=_blank id="L4" href="http://blog.csdn.net/i2cbus/article/details/21476401#L4" rel="#L4"> 4</a> <a target=_blank id="L5" href="http://blog.csdn.net/i2cbus/article/details/21476401#L5" rel="#L5"> 5</a> <a target=_blank id="L6" href="http://blog.csdn.net/i2cbus/article/details/21476401#L6" rel="#L6"> 6</a> <a target=_blank id="L7" href="http://blog.csdn.net/i2cbus/article/details/21476401#L7" rel="#L7"> 7</a> | service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd |
init.rc
1.6 system_server的启动过程如下:
在app_main.cpp的main函数中,有如下的代码:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> <a target=_blank id="L4" href="http://blog.csdn.net/i2cbus/article/details/21476401#L4" rel="#L4"> 4</a> | if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : ""); } |
app_main.cpp
runtime.start在正常情况下不会返回
在frameworks\base\core\java\com\android\internal\os\ZygoteInit.java的main中:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> | if (argv[1].equals("start-system-server")) { startSystemServer(); } |
ZygoteInit.java
startSystemServer中:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> <a target=_blank id="L4" href="http://blog.csdn.net/i2cbus/article/details/21476401#L4" rel="#L4"> 4</a> <a target=_blank id="L5" href="http://blog.csdn.net/i2cbus/article/details/21476401#L5" rel="#L5"> 5</a> <a target=_blank id="L6" href="http://blog.csdn.net/i2cbus/article/details/21476401#L6" rel="#L6"> 6</a> <a target=_blank id="L7" href="http://blog.csdn.net/i2cbus/article/details/21476401#L7" rel="#L7"> 7</a> <a target=_blank id="L8" href="http://blog.csdn.net/i2cbus/article/details/21476401#L8" rel="#L8"> 8</a> <a target=_blank id="L9" href="http://blog.csdn.net/i2cbus/article/details/21476401#L9" rel="#L9"> 9</a> <a target=_blank id="L10" href="http://blog.csdn.net/i2cbus/article/details/21476401#L10" rel="#L10"> 10</a> <a target=_blank id="L11" href="http://blog.csdn.net/i2cbus/article/details/21476401#L11" rel="#L11"> 11</a> <a target=_blank id="L12" href="http://blog.csdn.net/i2cbus/article/details/21476401#L12" rel="#L12"> 12</a> <a target=_blank id="L13" href="http://blog.csdn.net/i2cbus/article/details/21476401#L13" rel="#L13"> 13</a> <a target=_blank id="L14" href="http://blog.csdn.net/i2cbus/article/details/21476401#L14" rel="#L14"> 14</a> | private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); }。。。} |
startSystemServer.java
args中,有:--nice-name=system_server,这就是进程名system_server的由来
2 接下来我们来看看怎么去调试这个Android里Java层的最重要的进程,一般调试和开机调试
3 一般调试:
3.1 这种调试方法就是在Android启动完后,用adb连接Android,再调试system_process进程,实现起来是比较简单的,
3.2 无非就是在eclipse里创建一个名叫system_process的Android程序,然后在DDMS里选择system_process即可开始调试。
4 开机调试
4.1 有时我们需要调试一下system_process的初始化过程,因为上面的方法是在system_process已经初始化完之后开始调试的,用上面的方法是无能为力的,这就得另想办法。
4.2 搜索了下网络,没有找到比较实用的资源,于是自己研究了下。
4.3 其实也不是很麻烦:
找到SystemServer.java里的main函数,在函数的最开始加上几行代码:
<a target=_blank id="L1" href="http://blog.csdn.net/i2cbus/article/details/21476401#L1" rel="#L1"> 1</a> <a target=_blank id="L2" href="http://blog.csdn.net/i2cbus/article/details/21476401#L2" rel="#L2"> 2</a> <a target=_blank id="L3" href="http://blog.csdn.net/i2cbus/article/details/21476401#L3" rel="#L3"> 3</a> <a target=_blank id="L4" href="http://blog.csdn.net/i2cbus/article/details/21476401#L4" rel="#L4"> 4</a> | java.io.File f = new java.io.File("/system/debug"); if(f.exists()){ android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); android.os.Debug.waitForDebugger(); } |
SysemServer.java
4.4 解析下:
首先通过判断/system/debug是否存在来判断是否要等待调试器连接
android.os.Debug.waitForDebugger()就是等待调试器来连接,在调试器连接上之前代码不会往下执行
但是第一行代码就比较费解了,先来解析下什么叫ddm,ddm就是Dalvik Debug Monitor的缩写
android.ddm.DdmHandleAppName.setAppName就是要设置Java App在ddm里的名称。
如果不设置的话,你在DDMS里看到的Name一栏就会有一个“?”,这个时候,eclipse找不到对应的工程,所以就没法调试了。
所以这一行代码很重要
4.5 接下来就是重新编译代码并烧录了,这个看自己使用的是什么平台。
4.6 呵呵,是不是可以开机后用adb连接,再通过eclipse调试了?
5 这种方式的唯一缺陷就是要修改源代码,这个留着以后再研究,现在要做的是好好享受一下这种调试方法。
相关文章推荐
- Android平台实现开机调试system_process
- Android平台实现开机调试system_process
- AMD x2 ubuntu12.04 64bit基于emulator调试Android4.0.3源代码( system_process进程)
- eclipse调试android源码(system_process)
- Android实现开机自启动Service
- android平台从froyo 2.2开始支持jni单步调试了
- Android 远程调试 JNI 实现
- Android平台从Froyo 2.2开始支持jni单步调试了!
- Android实现开机自动运行程序
- Android平台从Froyo 2.2开始支持jni单步调试了!
- Android/Ophone平台2D游戏引擎实现系列文章 推荐
- Android实现开机自动运行程序
- CMMB在Android平台上的实现步骤简介
- Android平台上无线网卡自动扫描并关联AP的实现
- 高通Android平台硬件调试之Camera篇
- Android平台硬件调试之Camera篇
- Android实现开机自启动Service
- Android实现开机自动运行程序
- Android 实现真机远程调试并适应7寸屏大小 推荐
- android开发实现真机调试