SystemServer分析

1 SystemServer分析


SystemServer的进程名就是前面所说的“system_server”,是zygote进程“app_process”fork出来的第一个子嗣,其重要性不言而喻。下面我们简称其为SS。

1.1  SS的诞生

先回顾一下SS是如何创建的:




/*在zygoteinit.java的startsystemserver方法中*/

String args[] = {

"--setuid=1000",

"--setgid=1000", 
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",

"--capabilities=" + capabilities + "," + capabilities,

"--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(
//调用此函数创建SS

parsedArgs.uid, parsedArgs.gid,

parsedArgs.gids,

parsedArgs.debugFlags,

null,

parsedArgs.permittedCapabilities,

parsedArgs.effectiveCapabilities);

} catch
(IllegalArgumentException ex) {

throw new RuntimeException(ex);

}

下面看看forkSystemServer函数的具体内容 :




/*在Dalvik_dalvik_system_Zygote.cpp中)*/

/*

* native public static int nativeForkSystemServer(int uid, int
gid,

*     int[] gids, int debugFlags, int[][]
rlimits,

*     long permittedCapabilities, long
effectiveCapabilities);

*/

static void Dalvik_dalvik_system_Zygote_forkSystemServer(

const u4* args, JValue*
pResult)

{

pid_t pid;

/*根据参数fork一个子进程SS,并返回子进程的PID*/

pid = forkAndSpecializeCommon(args, true, true);

/* The zygote process checks whether the child
process has died or not. */

if (pid > 0) {

int status;

ALOGI("System server process
%d has been created", pid);

gDvm.systemServerPid = pid;
//保存SS的PID

/* There is a slight window
that the system server process has crashed

* but it went
unnoticed because we haven‘t published its pid yet. So

* we recheck here just
to make sure that all is well.

*/

/*函数退出前需要先检查创建的子进程SS是否退出了*/

if (waitpid(pid,
&status, WNOHANG) == pid) {

//如果SS退出了,那么zygote就自杀~

ALOGE("System server process %d has died. Restarting Zygote!", pid);

kill(getpid(), SIGKILL);

}

}

RETURN_INT(pid);

}

下面在看看forkAndSpecializeCommon函数主要完成两个工作:1,根据传入的参数对子进程做一些处理,如设置进程名,各种id等;2,就是调用很重要的信号处理函数setSignalHandler()。

该函数代码如下:




static void setSignalHandler()

{

int err;

struct sigaction sa;

memset(&sa, 0, sizeof(sa));

sa.sa_handler = sigchldHandler; //关联信号处理函数

err = sigaction (SIGCHLD, &sa, NULL);
//设置信号处理函数,该信号是子进程死亡的信号

if (err < 0) {

ALOGW("Error setting SIGCHLD
handler: %s", strerror(errno));

}

}

/*再看sigchldHandler函数,此函数由zygote在fork子进程之前调用!*/

static void sigchldHandler(int s)

{

pid_t pid;

int status;

while ((pid = waitpid(-1, &status, WNOHANG))
> 0) {

/* LOG死亡子进程的状态,以便调试*/

if (WIFEXITED(status)) {

if
(WEXITSTATUS(status)) {

ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)",

(int) pid, WEXITSTATUS(status));

}
else {

IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {

ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,

"Process %d exited cleanly
(%d)",

(int) pid, WEXITSTATUS(status));

}

}

} else if
(WIFSIGNALED(status)) {

if
(WTERMSIG(status) != SIGKILL) {

ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG,

"Process %d terminated by signal (%d)",

(int) pid, WTERMSIG(status));

}
else {

IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {

ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,

"Process %d terminated by signal (%d)",

(int) pid, WTERMSIG(status));

}

}

#ifdef WCOREDUMP

if
(WCOREDUMP(status)) {

ALOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core",

(int) pid);

}

#endif /* ifdef WCOREDUMP */

}

/*如果崩溃的子进程是SS,那么zygote就自杀,然后由init进程重新fork zygote进程,进而重启SS进程*/

if (pid ==
gDvm.systemServerPid) {

ALOG(LOG_INFO, ZYGOTE_LOG_TAG,

"Exit zygote because system server (%d) has terminated",

(int) pid);

kill(getpid(), SIGKILL);

}

}

if (pid < 0) {

ALOG(LOG_WARN,
ZYGOTE_LOG_TAG,

"Zygote SIGCHLD error in waitpid: %s",strerror(errno));

}

}

从上面的分析可以看出SS同zygote进程同生共死,可见SS的重要性!下面开始分析SS在Android系统中到底扮演者什么样的角色。

1.2  SS的使命

SS进程诞生后,就同zygote进程分道扬镳了。它有了自己的使命,那么它的使命是什么呢?这需要我们会到zygotinit.java文件中的startSystemServer方法中:




try {

……

pid
= Zygote.forkSystemServer(…);

} catch
(IllegalArgumentException ex) {

throw new RuntimeException(ex);

}

/* For child process */

if (pid == 0) {

//这里就是SS的使命

handleSystemServerProcess(parsedArgs);

}

/* handleSystemServerProcess 的详细代码如下*/

private static void handleSystemServerProcess(

ZygoteConnection.Arguments parsedArgs)

throws ZygoteInit.MethodAndArgsCaller {

closeServerSocket();
//首先关闭从zygote继承来的socket

//然后将umask值设为0077,这样的话新创建的文件和目录在默认情况下就//只有创建用户本身拥有读写权限了~

Libcore.os.umask(S_IRWXG |
S_IRWXO);

if (parsedArgs.niceName !=
null) {

Process.setArgV0(parsedArgs.niceName); //有昵称就设置昵称

}

if (parsedArgs.invokeWith !=
null) {

WrapperInit.execApplication(parsedArgs.invokeWith,

parsedArgs.niceName, parsedArgs.targetSdkVersion,

null, parsedArgs.remainingArgs);

} else {

/*调用zygoteInit函数,并将主要的参数传递给SS*/

RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs);

}

}

现在SS就进入到RuntimeInit类中了,zygoteInit的代码在RuntimeInit.java中,详细代码如下:




/**

* The main function called when started
through the zygote process. This

* could be unified with main(), if the native
code in nativeFinishInit()

* were rationalized with Zygote
startup.<p>

*

* Current recognized args:

* <ul>

*   <li> <code> [--]
&lt;start class name&gt;  &lt;args&gt;

* </ul>

*

* @param targetSdkVersion target SDK
version

* @param argv arg strings

*/

public static final void zygoteInit(int
targetSdkVersion, String[] argv)

throws
ZygoteInit.MethodAndArgsCaller {

if (DEBUG) Slog.d(TAG,
"RuntimeInit: Starting application from zygote");

/*Redirect System.out and System.err to the Android
log.分别对应log.info和log.warm*/

redirectLogStreams();

/*做一些常规初始化操作:很简单,可以看源代码中的注释*/

commonInit();

/*key1 native层的初始化*/

nativeZygoteInit();

/*key2
应用层的初始化,其实主要是通过调用invokeStaticMain函数来调用com.android.server.SystemServer类的main函数*/

applicationInit(targetSdkVersion, argv);

}

下面开始详细分析key1和key2。

1、nativeZygoteInit分析

nativeZygoteInit是一个native函数,它的实现在androidRuntime.cpp中




static void
com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject
clazz)

{

gCurRuntime->onZygoteInit();

}

gCurRuntime 是什么呢?回顾app_process(zygote)的main函数中有:

AppRuntime runtime;

AppRuntime类的定义:

class AppRuntime : public AndroidRuntime //
AppRuntime继承于AndroidRuntime

而gCurRuntime定义如下:

static AndroidRuntime* gCurRuntime = NULL;

//说明 gCurRuntime是一个AndroidRuntime类对象

AndroidRuntime的构造函数如下:

AndroidRuntime::AndroidRuntime() :

mExitWithoutCleanup(false)

{

//图形相关的初始化,skia库初始化。

SkGraphics::Init();

SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);

SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);

mOptions.setCapacity(20);

assert(gCurRuntime ==
NULL);

gCurRuntime = this; //
gCurRuntime
被设置为AndroidRuntime对象自己

}

由于SS是从zygote
fork出来的,所以它也拥有zygote进程中定义的这个gCurRuntime对象,那么onZygoteInit有什么作用呢?它的代码在App_main.cpp中:




virtual void onZygoteInit()

{

atrace_set_tracing_enabled(true);

//这个函数与binder有关,暂时不细究~

sp<ProcessState> proc
= ProcessState::self();

ALOGV("App process: starting
thread pool.\n");

proc->startThreadPool();
//启动一个线程,用于Binder通信

}

一言以蔽之,SS调用nativeZygoteInit后,将于Binder通信系统建立联系,这样SS就能够使用binder了。关于Binder的知识,将在后面详细介绍,这里不过多关注。

2、applicationInit分析

applicationInit主要是完成SS的应用层(java层)的初始化工作,该函数的核心功能在invokeStaticMain函数中:




private static void invokeStaticMain(String
className, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

//传递进来的参数className = “com.android.server.SystemServer”

Class<?> cl;

try {

cl =
Class.forName(className);

} catch
(ClassNotFoundException ex) {

throw new RuntimeException(

"Missing class when invoking static main " + className,

ex);

}

Method m;

try {

m =
cl.getMethod("main", new Class[] { String[].class });

} catch
(NoSuchMethodException ex) {

throw new RuntimeException(

"Missing static main on " + className, ex);

} catch (SecurityException
ex) {

throw new RuntimeException(

"Problem getting static main on " + className, ex);

}

int modifiers =
m.getModifiers();

if (!
(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)))
{

throw new RuntimeException(

"Main method is not public and static on " + className);

}

/*

* This throw gets
caught in ZygoteInit.main(), which responds

* by invoking the
exception‘s run() method. This arrangement

* clears up all the
stack frames that were required in setting

* up the process.

*/

/*重点来了!!!这里竟然抛出了一个异常!从源代码的注释可以知道,这个异常被ZygoteInit.main()截获(注意:我们此时是在SS进程中),然后调用该异常的run函数。

*/

throw new
ZygoteInit.MethodAndArgsCaller(m, argv);

}

/*回到zygoteinit.java的main函数看一下这个run 函数的功能*/

public void run() {

try
{

/*这个mMethod是com.android.server.SystemServer的main函数*/

mMethod.invoke(null, new Object[] { mArgs });

}
catch (IllegalAccessException ex) {

……

}

可以看出,invokeStaticMain抛出异常后会导致zygote进程调用com.android.server.SystemServer的main函数。那么为什么不直接在invokeStaticMain里面调用,转而使用这种方法呢?这个涉及到堆栈调用相关的只是,笔者还没弄明白,暂时搁置~

3、SS的真面目

Zygoteinit分裂产生的SS其实就是为了调用com.android.server.SystemServer的main函数!那么我们来看一看这个main函数到底做了什么:




public static void main(String[] args) {

……..

// Mmmmmm... more
memory!这尼玛是在搞笑?

dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

……

//加载libandroid_servers.so库

System.loadLibrary("android_servers");

Slog.i(TAG, "Entered the
Android system server!");

//
调用native函数,初始化native服务,其实就完成一个功能:

判断服务是否为sensor服务,如果是,就启动之。

nativeInit();

// This used to be its own
separate thread, but now it is

// just the loop we run on
the main thread.

ServerThread thr = new
ServerThread(); //创建一个服务线程

thr.initAndLoop();
//重点在这个函数!

}

}

initAndLoop函数完成了SS真正的功能:启动系统各项重要的服务,然后此线程进行消息循环,接收和处理消息。

1.3 对SS的总结

SS的启动流程:

Zygoteinit调用startSystemServer创建System_server进程;SS调用hanleSystemServerProcess完成自己的使命;hanleSystemServerProcess抛出异常MethodAndArgsCaller,最终调用com.android.server.SystemServer的main函数;main函数创建一个ServerThread线程,再调用这个线程的initAndLoop函数;在这个initAndLoop函数中,启动系统各项重要的服务,并将该线程加入到Binder通信系统中,进行消息循环。

时间: 2024-08-02 09:06:35

SystemServer分析的相关文章

Android systemserver分析ThrottleService 介绍

System Server是Android系统的核心,他在Dalvik虚拟机启动后立即开始初始化和运行.其它的系统服务在System Server进程的环境中运行./base/services/java/com/android/server/SystemServer.java Java代码   /** * This method is called from Zygote to initialize the system. This will cause the native * service

[深入理解Android卷二 全文-第三章]深入理解SystemServer

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在osc博客中全文转发这两本书的全部内容 第3章  深入理解SystemServer 本章主要内容: ·  分析SystemServer ·  分析EntropyService.DropBoxManagerService.DiskStatsService ·  分析DeviceStorageMonitorService.SamplingProfilerS

[深入理解Android卷一全文-第四章]深入理解zygote

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的所有内容. 第4章  深入理解Zygote 本章主要内容 ·  深入分析zygote,并介绍system_server进程的初始化工作. 本章涉及的源代码文件名称及位置 以下是我们本章分析的源代码文件名称及其位置. ·  App_main.cpp framework/base/cmds/app_process/App_m

SystemServer源码分析

从SystemServer的main函数入手 /** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } 这里创建了一个SystemServer并调用了它的run()函数,进入run()函数,这个方法内部比较多,分段分析: 时间处理 // If a device's clock is before 1970 (before 0), a

Android5 Zygote 与 SystemServer 启动流程分析

Android5 Zygote 与 SystemServer 启动流程分析 Android5 Zygote 与 SystemServer 启动流程分析 前言 zygote 进程 解析 zygoterc 启动 SystemServer 执行 ZygoteInitrunSelectLoop SystemServer 启动过程 Zygote 的 fork 本地方法分析 forkSystemServer ZygoteHookspreFork 创建 system_server 进程 ZygoteHooks

Android启动流程分析(十二) SystemServer

############################################# 本文为极度寒冰原创,转载请注明出处 ############################################# SystemServer也是系统的一个重要的守护进程,从SystemServer的进程中,我们看到了系统的各种关键的Service的启动. 另外,根据前面的zygote的分析,我们知道了systemServer在android的启动过程中是肯定要启动的. 因为在init.rc里面

Android5.0L中SensorService crash导致的systemserver重启问题分析

一.初步分析结论 sensorservice多线程机制存在问题,导致在disable accel sensor并释放相应内存和数据之后, 有很小的概率发生继续读取到未处理完的sensor事件,从而继续使用相应的内存和数据, 并且没有做相应的防御保护措施,最终引起指针地址操作错误. 二.解决方案 1.首先在可能发生错误的地方做好防御保护措施 2.对多线程进行同步,对于临界变量的操作都放置到临界区中,使用锁来保护. 三.具体分析过程 log中显示打出accel sensor被disable的信息,然

Android5.0L下因sensorservice crash导致systemserver重启的另外一种场景分析

一.出问题的场景 1.Sensorservice线程正在处理compass sensor事件的过程中,检查了一次buffer的指针的有效性,并在稍后会传递到AKM获取数据的函数接口中使用 2.Sensorservice线程所在进程的负责跨进程通信的Binder线程在sensorservice线程检查buffer指针之后没有真正使用之前, 收到了disable compass sensor的请求,从log中可以看到compass  sensor先是被disable,disable的同时会free上

Android的软件包管理服务PackageManagerService源码分析

Android系统下的apk程序都是通过名为PackageManagerService的包管理服务来管理的.PacketManagerService是安卓系统的一个重要服务,由SystemServer启动,主要实现apk程序包的解析,安装,更新,移动,卸载等服务.不管是系统apk(/system/app),还是我们手工安装上去的,系统所有的apk都是由其管理的. 以android 4.0.4的源码为例,android4.0.4/frameworks/base/services/java/com/