Android平台实现开机调试system_process

1 首先要理清一下什么是system_process
1.1 system_process是我们在DDMS可以看到的名称。设置的地方在ActivityThread.java:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
            
            
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中可以看到它是怎样启动起来的:

 1
 2
 3
 4
 5
 6
 7
            
            
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函数中,有如下的代码:

 1
 2
 3
 4
            
            
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中:


 1
 2
 3
            
            
if ( argv [ 1 ]. equals ( "start-system-server" )) {
startSystemServer ();
}
来自CODE的代码片
ZygoteInit.java


startSystemServer中:


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
            
            
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函数,在函数的最开始加上几行代码:


 1
 2
 3
 4
 5
 6
            
            
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 这种方式的唯一缺陷就是要修改源代码,这个留着以后再研究,现在要做的是好好享受一下这种调试方法。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值