您的位置:首页 > 移动开发 > Android开发

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:

<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());              ...          }          ...    }


来自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中可以看到它是怎样启动起来的:

<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


来自CODE的代码片
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" : "");    }


来自CODE的代码片
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();            }


来自CODE的代码片
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>
<a target=_blank id="L15" href="http://blog.csdn.net/i2cbus/article/details/21476401#L15" rel="#L15"> 15</a>
<a target=_blank id="L16" href="http://blog.csdn.net/i2cbus/article/details/21476401#L16" rel="#L16"> 16</a>
<a target=_blank id="L17" href="http://blog.csdn.net/i2cbus/article/details/21476401#L17" rel="#L17"> 17</a>
<a target=_blank id="L18" href="http://blog.csdn.net/i2cbus/article/details/21476401#L18" rel="#L18"> 18</a>
<a target=_blank id="L19" href="http://blog.csdn.net/i2cbus/article/details/21476401#L19" rel="#L19"> 19</a>
<a target=_blank id="L20" href="http://blog.csdn.net/i2cbus/article/details/21476401#L20" rel="#L20"> 20</a>
<a target=_blank id="L21" href="http://blog.csdn.net/i2cbus/article/details/21476401#L21" rel="#L21"> 21</a>
<a target=_blank id="L22" href="http://blog.csdn.net/i2cbus/article/details/21476401#L22" rel="#L22"> 22</a>
<a target=_blank id="L23" href="http://blog.csdn.net/i2cbus/article/details/21476401#L23" rel="#L23"> 23</a>
<a target=_blank id="L24" href="http://blog.csdn.net/i2cbus/article/details/21476401#L24" rel="#L24"> 24</a>
<a target=_blank id="L25" href="http://blog.csdn.net/i2cbus/article/details/21476401#L25" rel="#L25"> 25</a>
<a target=_blank id="L26" href="http://blog.csdn.net/i2cbus/article/details/21476401#L26" rel="#L26"> 26</a>
<a target=_blank id="L27" href="http://blog.csdn.net/i2cbus/article/details/21476401#L27" rel="#L27"> 27</a>
<a target=_blank id="L28" href="http://blog.csdn.net/i2cbus/article/details/21476401#L28" rel="#L28"> 28</a>
<a target=_blank id="L29" href="http://blog.csdn.net/i2cbus/article/details/21476401#L29" rel="#L29"> 29</a>
<a target=_blank id="L30" href="http://blog.csdn.net/i2cbus/article/details/21476401#L30" rel="#L30"> 30</a>
<a target=_blank id="L31" href="http://blog.csdn.net/i2cbus/article/details/21476401#L31" rel="#L31"> 31</a>
<a target=_blank id="L32" href="http://blog.csdn.net/i2cbus/article/details/21476401#L32" rel="#L32"> 32</a>
<a target=_blank id="L33" href="http://blog.csdn.net/i2cbus/article/details/21476401#L33" rel="#L33"> 33</a>
<a target=_blank id="L34" href="http://blog.csdn.net/i2cbus/article/details/21476401#L34" rel="#L34"> 34</a>
<a target=_blank id="L35" href="http://blog.csdn.net/i2cbus/article/details/21476401#L35" rel="#L35"> 35</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);        }。。。}


来自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函数,在函数的最开始加上几行代码:

<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>
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();        }


来自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 这种方式的唯一缺陷就是要修改源代码,这个留着以后再研究,现在要做的是好好享受一下这种调试方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: