本文主要介绍systemserver 如何启动main
备注:红色是zygote 进程,蓝色是systemserver 进程
1 代码流程
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer); -->创建进程systemserver
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
// 该部分已经运行在了SystemServer 进程中
r.run();----》实际运行了forksystemserver main , 真正进入systemserver
return;
}
}
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM
);
/* Containers run without this capability, so avoid setting it in that case */
if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
}
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000", ----》systemserver udi gid 设定
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",---->设定name
"--runtime-args",
"com.android.server.SystemServer", // class
};
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(---->进入Zygote.java forkSystemServer
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {--->如果有多个zygote , 等待
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();--->关闭zygote socket
return handleSystemServerProcess(parsedArgs);----》设定参数,zygote jni init , AndroidConfig等等
}
return null;
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
handleSystemServerProcess
/**
* Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName); --->设定进程的名字
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
..........
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);----> 加载systemserver class 路径
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);---->ZygoteInit.java 进入了zygote init
}
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
zygoteInit
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();----》 runtime common 初始化
ZygoteInit.nativeZygoteInit();--->进入nativ zygote 初始化
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);--》找到systemserver class 的main
}
frameworks/base/core/java/com/android/internal/os/RunTimeInit.java
findStaticMain
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class> cl;
try {
cl = Class.forName(className, true, classLoader);
} 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.
*/
return new MethodAndArgsCaller(m, argv);--->实际是Runnable 类型
}
frameworks/base/core/java/com/android/internal/os/RunTimeInit.java
MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() { ----->class MethodAndArgsCaller run 方法
try {
mMethod.invoke(null, new Object[] { mArgs });---》调用systemserver main,反射
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
MethodAndArgsCaller 最后返回ZygoteInit.java, 在fork systemserver 进程中,调用了它的run , run 函数进入了systemserver的main
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
........
1 zygote 与systemserver 关系
systemserver 挂掉, zygote 也会kill
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
ForkAndSpecializeCommon
SetSigChldHandler();
sigset_t sigchld;
sigemptyset(&sigchld);
sigaddset(&sigchld, SIGCHLD);
........
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
SetSigChldHandler
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler;----> callback函数
int err = sigaction(SIGCHLD, &sa, NULL); ---》 注册,收到SIGCHLD 信号 ,就调用SigChldHandler
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
SigChldHandler
// This signal handler is for zygote mode, since the zygote must reap its children
static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
// It's necessary to save and restore the errno during this function.
// Since errno is stored per thread, changing it here modifies the errno
// on the thread on which this signal handler executes. If a signal occurs
// between a call and an errno check, it's possible to get the errno set
// here.
// See b/23572286 for extra information.
int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Log process-death status that we care about. In general it is
// not safe to call LOG(...) from a signal handler because of
// possible reentrancy. However, we know a priori that the
// current implementation of LOG() is safe to call from a SIGCHLD
// handler in the zygote process. If the LOG() implementation
// changes its locking strategy or its use of syscalls within the
// lazy-init critical section, its use here may become unsafe.
if (WIFEXITED(status)) {
if (WEXITSTATUS(status)) {
ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGKILL) {
ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
}
if (WCOREDUMP(status)) {
ALOGI("Process %d dumped core.", pid);
}
}
// If the just-crashed process is the system_server, bring down zygote
// so that it is restarted by init and system server will be restarted
// from there.
if (pid == gSystemServerPid) {
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL); ---> system server 挂掉,zygote 也会 SIGKILL
}
}
// Note that we shouldn't consider ECHILD an error because
// the secondary zygote might have no children left to wait for.
if (pid < 0 && errno != ECHILD) {
ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
}
errno = saved_errno;
}