一 System Server
System Server是Zygote启动的第一个进程,它的核心功能是启动和管理Android系统的各类服务。
1.0 startSystemServer
private static boolean startSystemServer(String abiList, String socketName) // abiList为arm64-v8a,socketName为zygote
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits( // Linux的Capabilities安全机制,可参考include/uapi/linux/capability.h
OsConstants.CAP_BLOCK_SUSPEND, // 允许阻止系统挂起
OsConstants.CAP_KILL, // 允许对不属于自己的进程发送信号
OsConstants.CAP_NET_ADMIN, // 允许执行网络管理任务
OsConstants.CAP_NET_BIND_SERVICE, // 允许绑定到小于1024的端口
OsConstants.CAP_NET_BROADCAST, // 允许网络广播和多播访问
OsConstants.CAP_NET_RAW, // 允许使用原始套接字
OsConstants.CAP_SYS_MODULE, // 允许插入和删除内核模块
OsConstants.CAP_SYS_NICE, // 允许提升优先级及设置其他进程的优先级
OsConstants.CAP_SYS_RESOURCE, // 忽略资源限制
OsConstants.CAP_SYS_TIME, // 允许改变系统时钟
OsConstants.CAP_SYS_TTY_CONFIG // 允许配置TTY设备
);
/* 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,1021,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server", // 进程名是system_server
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args); // 将参数转化为Arguments格式
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( // // fork system_server进程
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) { // fork返回0,说明在子进程(system_server)中
if (hasSecondZygote(abiList)) { // 判断是否存在第二个zygote需要启动,由于64位系统为了兼容32位应用程序,将同时启动zygote64和zygote,所以这里为true
waitForSecondaryZygote(socketName); // 等待zygote_secondary启动完成
}
handleSystemServerProcess(parsedArgs); // 完成system_server进程剩余的工作
}
return true;
}
二 forkSystemServer
2.0 forkSystemServer
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
int pid = nativeForkSystemServer( // 调用native方法fork system_server进程
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true); // 在system_server进程中重新使能Systrace追踪
}
VM_HOOKS.postForkCommon();
return pid;
}
public void preFork() {
Daemons.stop(); // 停止HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon等四个Daemon子线程
waitUntilAllThreadsStopped(); // 等待所有子线程结束
token = nativePreFork(); // 完成一些运行时fork前期工作
}
public void postForkCommon() {
Daemons.start(); // 启动HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon等四个Daemon子线程
}
2.1 com_android_internal_os_Zygote_nativeForkSystemServer
nativeForkSystemServer对应JNI函数是com_android_internal_os_Zygote_nativeForkSystemServer
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL); // fork子进程
if (pid > 0) { // fork返回大于0,说明在父进程(zygote64)中
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
gSystemServerPid = 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.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) { // 等待子进程退出,WNOHANG表示非阻塞 // 这里是处理system_server刚创建就crash的情况
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); // 当system_server进程死亡后,需要重启zygote进程
}
}
return pid;
}
2.2 ForkAndSpecializeCommon
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
SetSigChldHandler(); // 设置SIGCHLD信号处理函数 // 子进程的SIGCHLD信号处理函数会在后面改回系统默认函数
#ifdef ENABLE_SCHED_BOOST
SetForkLoad(true);
#endif
pid_t pid = fork(); // fork子进程
if (pid == 0) { // 进入子进程
// The child process.
gMallocLeakZygoteChild = 1;
// Clean up any descriptors which must be closed immediately
DetachDescriptors(env, fdsToClose); // 关闭并清除文件描述符 // 由于fdsToClose为null,所以没有关闭任何文件描述符
// Keep capabilities across UID change, unless we're staying root.
if (uid != 0) {
EnableKeepCapabilities(env); // 非root用户,禁止动态改变进程的权限
}
DropCapabilitiesBoundingSet(env); // 取消进程的已有的Capabilities权限
bool use_native_bridge = !is_system_server && (instructionSet != NULL)
&& android::NativeBridgeAvailable();
if (use_native_bridge) {
ScopedUtfChars isa_string(env, instructionSet);
use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
}
if (use_native_bridge && dataDir == NULL) {
// dataDir should never be null if we need to use a native bridge.
// In general, dataDir will never be null for normal applications. It can only happen in
// special cases (for isolated processes which are not associated with any app). These are
// launched by the framework and should not be emulated anyway.
use_native_bridge = false;
ALOGW("Native bridge will not be used because dataDir == NULL.");
}
if (!MountEmulatedStorage(uid, mount_external, use_native_bridge)) { // mount命名空间
ALOGW("Failed to mount emulated storage: %s", strerror(errno));
if (errno == ENOTCONN || errno == EROFS) {
// When device is actively encrypting, we get ENOTCONN here
// since FUSE was mounted before the framework restarted.
// When encrypted device is booting, we get EROFS since
// FUSE hasn't been created yet by init.
// In either case, continue without external storage.
} else {
RuntimeAbort(env, __LINE__, "Cannot continue without emulated storage");
}
}
if (!is_system_server) {
int rc = createProcessGroup(uid, getpid()); // 对于非system_server子进程,则创建进程组
if (rc != 0) {
if (rc == -EROFS) {
ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
} else {
ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
}
}
}
SetGids(env, javaGids); // 设置组代码
SetRLimits(env, javaRlimits); // 设置资源limit // javaRlimits等于null,不限制
if (use_native_bridge) {
ScopedUtfChars isa_string(env, instructionSet);
ScopedUtfChars data_dir(env, dataDir);
android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
}
int rc = setresgid(gid, gid, gid); // 分别设置真实的,有效的和保存过的组标识号
if (rc == -1) {
ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
RuntimeAbort(env, __LINE__, "setresgid failed");
}
rc = setresuid(uid, uid, uid); // 分别设置真实的,有效的和保存过的用户标识号
if (rc == -1) {
ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
RuntimeAbort(env, __LINE__, "setresuid failed");
}
if (NeedsNoRandomizeWorkaround()) {
// Work around ARM kernel ASLR lossage (http://b/5817320).
int old_personality = personality(0xffffffff);
int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
if (new_personality == -1) {
ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
}
}
SetCapabilities(env, permittedCapabilities, effectiveCapabilities); // 配置新的Capabilities权限
SetSchedulerPolicy(env); // 设置调度策略
const char* se_info_c_str = NULL;
ScopedUtfChars* se_info = NULL;
if (java_se_info != NULL) {
se_info = new ScopedUtfChars(env, java_se_info);
se_info_c_str = se_info->c_str();
if (se_info_c_str == NULL) {
RuntimeAbort(env, __LINE__, "se_info_c_str == NULL");
}
}
const char* se_name_c_str = NULL;
ScopedUtfChars* se_name = NULL;
if (java_se_name != NULL) {
se_name = new ScopedUtfChars(env, java_se_name);
se_name_c_str = se_name->c_str();
if (se_name_c_str == NULL) {
RuntimeAbort(env, __LINE__, "se_name_c_str == NULL");
}
}
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); // 设置SELinux的domain上下文
if (rc == -1) {
ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
is_system_server, se_info_c_str, se_name_c_str);
RuntimeAbort(env, __LINE__, "selinux_android_setcontext failed");
}
// Make it easier to debug audit logs by setting the main thread's name to the
// nice name rather than "app_process".
if (se_info_c_str == NULL && is_system_server) {
se_name_c_str = "system_server";
}
if (se_info_c_str != NULL) {
SetThreadName(se_name_c_str);
}
delete se_info;
delete se_name;
UnsetSigChldHandler(); // 将子进程system_server的SIGCHLD信号的处理函数修改回系统默认函数
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server, instructionSet); // 调用zygote.callPostForkChildHooks()方法 // 完成一些运行时的后期工作
if (env->ExceptionCheck()) {
RuntimeAbort(env, __LINE__, "Error calling post fork hooks.");
}
} else if (pid > 0) { // 进入父进程,即zygote64进程
// the parent process
#ifdef ENABLE_SCHED_BOOST
// unset scheduler knob
SetForkLoad(false);
#endif
}
return pid;
}
2.3 SetSigChldHandler
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler;
int err = sigaction(SIGCHLD, &sa, NULL); // 设置信号处理函数,SIGCHLD是子进程终止的信号
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
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) { // 当system_server退出时
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL); // zygote64杀死自己,init将会重启zygote64
}
}
// 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;
}
三 handleSystemServerProcess
3.0 handleSystemServerProcess
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket(); // 关闭从父进程zygote64复制而来的Socket
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO); // 设置system_server新建文件时预设的权限掩码
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName); // 设置当前进程名为system_server
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); // SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath); // 进行dexopt优化
}
if (parsedArgs.invokeWith != null) { // system_server进程invokeWith为null
String[] args = parsedArgs.remainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); // 创建类加载器
Thread.currentThread().setContextClassLoader(cl); // 设置当前线程(system_server)的类加载器
}
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); // 调用zygoteInit函数
}
/* should never reach here */
}
3.1 performSystemServerDexOpt
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
final InstallerConnection installer = new InstallerConnection(); // 创建一个InstallerConnection
installer.waitForConnection(); // 连接installd服务端Socket
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
try {
for (String classPathElement : classPathElements) {
final int dexoptNeeded = DexFile.getDexOptNeeded(
classPathElement, instructionSet, "speed", false /* newProfile */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
dexoptNeeded, 0 /*dexFlags*/); // 进行dexopt优化
}
}
} catch (IOException ioe) {
throw new RuntimeException("Error starting system_server", ioe);
} finally {
installer.disconnect(); // 断开与installd服务端Socket连接
}
}
四 zygoteInit
4.0 zygoteInit
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit"); // 开始Systrace追踪RuntimeInit
redirectLogStreams(); // 重定向log输出
commonInit(); // 进行一些通用的初始化
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
4.1 commonInit
private static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
/* set default handler; this applies to all threads in the VM */
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); // 为当前线程的未捕捉异常设置默认的处理方法
/*
* Install a TimezoneGetter subclass for ZoneInfo.db
*/
TimezoneGetter.setInstance(new TimezoneGetter() { // 设置时区
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone"); // persist.sys.timezone=Asia/Shanghai
}
});
TimeZone.setDefault(null);
/*
* Sets handler for java.util.logging to use Android log facilities.
* The odd "new instance-and-then-throw-away" is a mirror of how
* the "java.util.logging.config.class" system property works. We
* can't use the system property here since the logger has almost
* certainly already been initialized.
*/
LogManager.getLogManager().reset(); // 重置log设置
new AndroidConfig(); // 设置Android log
/*
* Sets the default HTTP User-Agent used by HttpURLConnection.
*/
String userAgent = getDefaultUserAgent(); // 获取默认的UserAgent
System.setProperty("http.agent", userAgent); // 设置默认的HTTP User-agent,用于HttpURLConnection
/*
* Wire socket tagging to traffic stats.
*/
NetworkManagementSocketTagger.install(); // 网络流量统计
/*
* If we're running in an emulator launched with "-trace", put the
* VM into emulator trace profiling mode so that the user can hit
* F9/F10 at any time to capture traces. This has performance
* consequences, so it's not something you want to do always.
*/
String trace = SystemProperties.get("ro.kernel.android.tracing");
if (trace.equals("1")) {
Slog.i(TAG, "NOTE: emulator trace profiling enabled");
Debug.enableEmulatorTraceOutput();
}
initialized = true;
}
4.2 com_android_internal_os_RuntimeInit_nativeZygoteInit
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
virtual void onZygoteInit()
{
sp
proc = ProcessState::self(); // 构造进程的ProcessState对象
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 启动线程池
}
4.3 applicationInit
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true); // true代表应用程序退出时做清除动作
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); // 设置虚拟机运行时的内存堆的利用率
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv); // 解析参数
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); // 停止Systrace追踪RuntimeInit
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader); // 调用com.android.server.SystemServer类的main函数
}
五 invokeStaticMain
5.0 invokeStaticMain
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class> cl;
try {
cl = Class.forName(className, true, classLoader); // 装载com.android.server.SystemServer类,并对其进行初始化
} 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 }); // 获取com.android.server.SystemServer类的main方法
} 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(); // 获取main方法的修饰符
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { // Java规范定义了main函数的声明必须是 public static void main(String args[])
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.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv); // 抛出MethodAndArgsCaller异常
}
5.1 MethodAndArgsCaller
回到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 的main函数
public static void main(String argv[]) {
try {
...
if (startSystemServer) {
startSystemServer(abiList, socketName); // 启动system_server进程
}
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) { // 捕获MethodAndArgsCaller异常
caller.run(); // 调用MethodAndArgsCaller的run方法
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
5.2 MethodAndArgsCaller.run
MethodAndArgsCaller是一个异常类
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method; // com.android.server.SystemServer类的main方法
mArgs = args; // 传递给SystemServer类main方法的参数
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs }); // 调用com.android.server.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);
}
}