http://blog.csdn.net/xichangbao/article/details/53131428
一 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<ProcessState> 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); } }