Android应用进程的创建过程
2018-07-02 本文已影响11人
lbtrace
基于Android 7.0源码分析
以Launcher点击应用启动应用为例
ActivityManagerService(system_server)请求Zygote创建应用进程的过程
当运行应用时,如果应用进程还没有创建,ActivityManagerService
会请求Zygote
fork进程,下面从ActivityManagerService
的startProcessLocked()
开始分析。
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
// keepIfLarge为true,knownToBeDead为true,intentFlags为0,allowWhileBooting为false
// isolated为false
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
// isolated通常为false,与安全相关
if (!isolated) {
// 查找ProcessRecord,非isolated进程,可以重用先前的ProcessRecord
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkTime(startTime, "startProcess: after getProcessRecord");
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// If we are in the background, then check to see if this process
// is bad. If so, we will just silently fail.
// 检查是否是经常crash的应用
if (mAppErrors.isBadProcessLocked(info)) {
if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
+ "/" + info.processName);
return null;
}
} else {
// When the user is explicitly starting a process, then clear its
// crash count so that we won't make it bad until they see at
// least one crash dialog again, and make the process good again
// if it had been bad.
if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
+ "/" + info.processName);
// 清理进程crash信息
mAppErrors.resetProcessCrashTimeLocked(info);
if (mAppErrors.isBadProcessLocked(info)) {
EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
UserHandle.getUserId(info.uid), info.uid,
info.processName);
mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
// If this is an isolated process, it can't re-use an existing process.
// isolated进程不能重用ProcessRecord
app = null;
}
// app launch boost for big.little configurations
// use cpusets to migrate freshly launched tasks to big cores
// 对于大小核架构,使用cpuset,将前台任务迁移到大核上
nativeMigrateToBoost();
mIsBoosted = true;
mBoostStartTime = SystemClock.uptimeMillis();
// 设置Boost超时取消
Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
......
if (app != null && app.pid > 0) {
if ((!knownToBeDead && !app.killed) || app.thread == null) {
// 应用进程已经运行或者即将运行
// We already have the app running, or are waiting for it to
// come up (we have a pid but not yet its thread), so keep it.
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: done, added package to proc");
return app;
}
// An application record is attached to a previous process,
// clean it up now.
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
// ProcessRecord关联到先前的进程,清理
checkTime(startTime, "startProcess: bad proc running, killing");
killProcessGroup(app.uid, app.pid);
handleAppDiedLocked(app, true, true);
checkTime(startTime, "startProcess: done killing old proc");
}
......
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
// 创建新的ProcessRecord
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
// 设置crashHandler
app.crashHandler = crashHandler;
checkTime(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: added package to existing proc");
}
......
// 系统尚未准备好,暂缓启动进程,待启动进程添加到mProcessesOnHold
if (!mProcessesReady
&& !isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mProcessesOnHold.contains(app)) {
mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
"System not ready, putting on hold: " + app);
checkTime(startTime, "startProcess: returning with proc on hold");
return app;
}
checkTime(startTime, "startProcess: stepping in to startProcess");
// 启动应用进程
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}
- 注意
ProcessRecord
可被重用
下面继续看startProcessLocked()
实现
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
if (app.pid > 0 && app.pid != MY_PID) {
// 重用的ProcessRecord,pid > 0
checkTime(startTime, "startProcess: removing from pids map");
// 从pids map中移除,移除进程启动超时消息
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
checkTime(startTime, "startProcess: done removing from pids map");
// pid置0
app.setPid(0);
}
mProcessesOnHold.remove(app);
......
try {
try {
// 获取userId,通常为0
final int userId = UserHandle.getUserId(app.uid);
// 检查应用的package状态
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
......
int debugFlags = 0;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// 应用可调式
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
// Also turn on CheckJNI for debuggable apps. It's quite
// awkward to turn on otherwise.
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
// Run the app in safe mode if its manifest requests so or the
// system is booted in safe mode.
if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
mSafeMode == true) {
// 运行在安全模式
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
......
// abiOverride为null使用app的primaryCpuAbi
String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
if (requiredAbi == null) {
// 如果requiredAbi为null,使用系统支持的CPUABI列表中的第一个
requiredAbi = Build.SUPPORTED_ABIS[0];
}
String instructionSet = null;
if (app.info.primaryCpuAbi != null) {
// 查找CPUABI对应的指令集
// armeabi => arm
// armeabi-v7a => arm
// arm64-v8a => arm64
instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
}
// 进程所属额外的group ids
app.gids = gids;
app.requiredAbi = requiredAbi;
app.instructionSet = instructionSet;
......
boolean isActivityProcess = (entryPoint == null);
// 设置进程入口,通常为"android.app.ActivityThread"
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
// 请求Zygote fork进程并等待Zygote发送进程启动结果
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (app.isolated) {
mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
}
// 通知BatteryStatsService进程启动
mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
checkTime(startTime, "startProcess: done updating battery stats");
// AM_PROC_START事件log
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
......
if (app.persistent) {
// 记录Phone进程的pid
Watchdog.getInstance().processStarted(app.processName, startResult.pid);
}
......
// 设置ProcessRecord新进程信息
app.setPid(startResult.pid);
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
app.killed = false;
app.killedByAm = false;
checkTime(startTime, "startProcess: starting to update pids map");
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
// 设置应用进程attach到ActivityManagerService的超时检测
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
......
}
}
下面看Process
的start()
方法
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
- processClass 进程入口类名
- niceName 进程名
- uid 进程uid
- gid 进程group id(通常等于uid)
- gids 进程所属额外的group ids
- debugFlags 进程调试标志位
- targetSdkVersion 应用目标sdk
- seInfo 进程的SELinux信息
- abi 进程运行的abi
- instructionSet 进程运行的指令集
- appDataDir 应用的数据路径(/data/user/0/xxx)
下面看startViaZygote()
的实现
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
// 通过ArrayList传递启动参数给Zygote
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
......
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
// 如果还没有创建Socket,创建Socket用于与Zygote通信
// ZygoteState用于管理与Zygote通信的状态
// 通常在arm64系统中,通常primaryZygoteState与secondaryZygoteState分别对应
// 进程Zygote64与Zygote(取决于*.rc文件配置)
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
// 如果primaryZygoteState没有创建或已经关闭,创建它
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
// 检查abi是否匹配primaryZygoteState
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
// 检查abi是否匹配secondaryZygoteState
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
// 向Zygote进程(Zygote64/Zygote)发送参数列表,请求fork进程
private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
// 向Zygote发送参数的数目以及参数字符串
writer.write(Integer.toString(args.size()));
writer.newLine();
int sz = args.size();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
if (arg.indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx(
"embedded newlines not allowed");
}
writer.write(arg);
writer.newLine();
}
writer.flush();
// 读取Zygote发送结果,可能需要等待
ProcessStartResult result = new ProcessStartResult();
result.pid = inputStream.readInt();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
result.usingWrapper = inputStream.readBoolean();
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
下面看Zygote收到请求后,创建应用进程的过程。Zygote进程启动后,会调用runSelectLoop()
等待客户端的连接请求,下面分析runSelectLoop()
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
......
// 运行runSelectLoop,等待客户端连接
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
// 子进程中调用MethodAndArgsCaller的run方法
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
// 监听文件描述符集pollFds
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
// 接收客户端的连接请求,创建ZygoteConnection
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
// 读取、处理客户端请求
ne = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
// 在子进程中会抛出ZygoteInit.MethodAndArgsCaller
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
// 读取客户端发送的参数列表
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket();
return true;
}
......
try {
// 解析参数列表
parsedArgs = new Arguments(args);
if (parsedArgs.abiListQuery) {
// 处理客户端查询abiList请求(客户端socket创建时)
return handleAbiListQuery();
}
......
// 安全检查
applyUidSecurityPolicy(parsedArgs, peer);
applyInvokeWithSecurityPolicy(parsedArgs, peer);
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
......
// 避免子进程文件描述符泄露,需要关闭Zygote socket文件描述符
int [] fdsToClose = { -1, -1 };
FileDescriptor fd = mSocket.getFileDescriptor();
if (fd != null) {
fdsToClose[0] = fd.getInt$();
}
fd = ZygoteInit.getServerSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}
fd = null;
// fork进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
}
try {
if (pid == 0) {
// in child
// 子进程中执行
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 处理子进程fork后的设置,见下一节
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw ZygoteInit.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
// Zygote进程中执行
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
下面看forkAndSpecialize
的实现
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir) {
// fork之前的准备工作
VM_HOOKS.preFork();
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {
// 在子进程中使能trace
Trace.setTracingEnabled(true);
// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
// fork之后的工作
VM_HOOKS.postForkCommon();
return pid;
}
public void preFork() {
// 停止4个守护线程
Daemons.stop();
// 等待守护线程结束
waitUntilAllThreadsStopped();
// 整理heap,如果有zygote heap基本上没有工作
token = nativePreFork();
}
public static void stop() {
HeapTaskDaemon.INSTANCE.stop();
ReferenceQueueDaemon.INSTANCE.stop();
FinalizerDaemon.INSTANCE.stop();
FinalizerWatchdogDaemon.INSTANCE.stop();
}
public void postForkCommon() {
// 启动4个守护线程
Daemons.start();
}
这里介绍下4个守护线程:
- HeapTaskDaemon
- 用于处理GC tasks,包括Heap裁减,Heap垃圾回收器切换,Heap GC
- ReferenceQueueDaemon
- 当Reference关联的对象被GC回收时,GC将Reference添加到静态链表(ReferenceQueue.unenqueued)中,ReferenceQueueDaemon负责将静态链表中的Reference添加到关联的ReferenceQueue中
- FinalizerDaemon
- 执行对象的
finalize
方法,对于FinalizerDaemon的执行过程以后讨论
- 执行对象的
- FinalizerWatchdogDaemon
- 监视FinalizerDaemon
下面看nativeForkAndSpecialize
的实现
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
jlong capabilities = 0;
......
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
se_name, false, fdsToClose, instructionSet, appDataDir);
}
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();
......
// fork进程
pid_t pid = fork();
if (pid == 0) {
// 子进程
// The child process.
gMallocLeakZygoteChild = 1;
// Clean up any descriptors which must be closed immediately
// 关闭继承自zygote的socket文件描述符
DetachDescriptors(env, fdsToClose);
......
if (!is_system_server) {
// 创建进程组
int rc = createProcessGroup(uid, getpid());
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));
}
}
}
// 设置进程所属额外的groups
SetGids(env, javaGids);
// 设置资源限制
SetRLimits(env, javaRlimits);
// 通常不使用native bridge
// native bridge用于运行带有与系统不同的处理器架构native库的应用
if (use_native_bridge) {
ScopedUtfChars isa_string(env, instructionSet);
ScopedUtfChars data_dir(env, dataDir);
android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
}
// 设置real GID/effective GID/saved set-user-ID GID
int rc = setresgid(gid, gid, gid);
if (rc == -1) {
ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
RuntimeAbort(env, __LINE__, "setresgid failed");
}
// 设置real UID/effective UID/saved set-user-ID UID
rc = setresuid(uid, uid, uid);
if (rc == -1) {
ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
RuntimeAbort(env, __LINE__, "setresuid failed");
}
if (NeedsNoRandomizeWorkaround()) {
// 针对低版本kernel,弥补ASLR(地址空间布局随机化)的缺失
// 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);
// 设置调度策略(SP_DEFAULT)
SetSchedulerPolicy(env);
......
// 设置Selinux策略
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
......
if (se_info_c_str != NULL) {
// 设置进程名
SetThreadName(se_name_c_str);
}
delete se_info;
delete se_name;
// 取消SIGCHLD信号处理
UnsetSigChldHandler();
// 调用Zygote的callPostForkChildHooks方法
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server, instructionSet);
if (env->ExceptionCheck()) {
RuntimeAbort(env, __LINE__, "Error calling post fork hooks.");
}
} else if (pid > 0) {
// the parent process
#ifdef ENABLE_SCHED_BOOST
// unset scheduler knob
SetForkLoad(false);
#endif
}
return pid;
}
下面看Zygote
的callPostForkChildHooks
的实现
private static void callPostForkChildHooks(int debugFlags, boolean isSystemServer,
String instructionSet) {
VM_HOOKS.postForkChild(debugFlags, isSystemServer, instructionSet);
}
public void postForkChild(int debugFlags, boolean isSystemServer, String instructionSet) {
// 在Zygote fork之后的子进程中调用
nativePostForkChild(token, debugFlags, isSystemServer, instructionSet);
Math.setRandomSeedInternal(System.currentTimeMillis());
}
nativePostForkChild()
是个native方法,下面看它的实现。
static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
jclass,
jlong token,
jint debug_flags,
jboolean is_system_server,
jstring instruction_set) {
Thread* thread = reinterpret_cast<Thread*>(token);
// Our system thread ID, etc, has changed so reset Thread state.
thread->InitAfterFork();
EnableDebugFeatures(debug_flags);
......
if (instruction_set != nullptr && !is_system_server) {
// 指令集不为空且非system_server
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload;
if (isa != kNone && isa != kRuntimeISA) {
action = Runtime::NativeBridgeAction::kInitialize;
}
// 设置heap、创建Jit等
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, action, isa_string.c_str());
} else {
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, Runtime::NativeBridgeAction::kUnload, nullptr);
}
}
void Runtime::InitNonZygoteOrPostFork(
JNIEnv* env, bool is_system_server, NativeBridgeAction action, const char* isa) {
is_zygote_ = false;
// 通常is_native_bridge_loaded_为false, See ro.dalvik.vm.native.bridge属性
if (is_native_bridge_loaded_) {
switch (action) {
case NativeBridgeAction::kUnload:
UnloadNativeBridge();
is_native_bridge_loaded_ = false;
break;
case NativeBridgeAction::kInitialize:
InitializeNativeBridge(env, isa);
break;
}
}
// Create the thread pools.
heap_->CreateThreadPool();
// Reset the gc performance data at zygote fork so that the GCs
// before fork aren't attributed to an app.
// 重置GC性能数据
heap_->ResetGcPerformanceInfo();
if (!is_system_server &&
!safe_mode_ &&
(jit_options_->UseJitCompilation() || jit_options_->GetSaveProfilingInfo()) &&
jit_.get() == nullptr) {
// Note that when running ART standalone (not zygote, nor zygote fork),
// the jit may have already been created.
// 创建Jit
CreateJit();
}
// 启动Signal Catcher Thread
StartSignalCatcher();
// Start the JDWP thread. If the command-line debugger flags specified "suspend=y",
// this will pause the runtime, so we probably want this to come last.
Dbg::StartJdwp();
}
至此,应用进程基本创建完成,下面看应用进程创建后设置的过程。
应用进程创建后设置的过程
回到ZygoteConnection
的runOnce
中,下面分析子进程fork后的设置,也就是handleChildProc
的实现。
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
/**
* By the time we get here, the native code has closed the two actual Zygote
* socket connections, and substituted /dev/null in their place. The LocalSocket
* objects still need to be closed properly.
*/
// 关闭与连接关联的socket
closeSocket();
// 关闭清理Zygote socket
ZygoteInit.closeServerSocket();
......
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// 这里invokeWith为null
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
下面看RuntimeInit
的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");
// System.out重定向到Android log
redirectLogStreams();
// 设置未捕获异常处理,Logger log写入Android log等
commonInit();
// 支持Binder通信
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
在Android应用中使用System.out以及Logger打印log,通过logcat也能看到。
下面看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);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
// heap目标利用率设置
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);
// Remaining arguments are passed to the start class's static main
// 调用ActivityThread的main方法
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
// 获取ActivityThread类对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// ActivityThread的main方法
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();
// main方法必须是public static
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.
*/
// 为了进程启动时清理栈帧,抛出MethodAndArgsCaller,在ZygoteInit.main方法中捕获处理
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
回到ZygoteInit
的main
方法中。
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
......
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
// 调用MethodAndArgsCaller的run方法
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
public static class MethodAndArgsCaller extends Exception
implements Runnable {
......
public void run() {
try {
// 调用ActivityThread的main方法
mMethod.invoke(null, new Object[] { mArgs });
} 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);
}
}
}
对于Android应用进程的启动过程,这里分析到ActivityThread
的main
方法,对于后续流程暂不讨论。