文章目录
- 日志抓取
- 结合日志与源码分析
- systemServer zygote创建时序图
- 一般应用 zygote 创建时序图
- 向 zygote socket 发送数据时序图
本文首发地址 https://h89.cn/archives/298.html
最新更新地址 https://gitee.com/chenjim/chenjimblog
本文主要结合日志和代码看安卓 14 中 Zygote 启动相关流程
日志抓取
先抓一份开机日志
adb reboot && adb wait-for-device shell logcat -b all > all.log
过滤出 zygote 相关日志
cat all.log | grep -i Zygote > all.Zygote.log
以上完整日志文件 https://gitee.com/chenjim/ResData/tree/master/boot.01.log
我们看一下 日志文件 all.Zygote.log , 部分日志如下
07-01 21:43:43.516 0 0 I init : Added '/system/etc/init/hw/init.zygote64.rc' to import list
07-01 21:43:43.516 0 0 I init : Parsing file /system/etc/init/hw/init.zygote64.rc...
07-01 21:43:45.841 0 0 I init : processing action (ro.crypto.state=encrypted && ro.crypto.type=file && zygote-start) from (/system/etc/init/hw/init.rc:1090)
07-01 21:43:45.880 0 0 I init : starting service 'zygote'...
07-01 21:43:45.881 0 0 I init : Created socket '/dev/socket/zygote', mode 660, user 0, group 1000
07-01 21:43:46.329 282 282 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
07-01 21:43:46.422 0 0 I init : service 'zygote' requested start, but it is already running (flags: 4)
07-01 21:43:46.527 282 282 I zygote64: option[0]=-Xzygote
07-01 21:43:47.411 282 282 D Zygote : begin preload
07-01 21:43:47.414 282 282 I Zygote : Calling ZygoteHooks.beginPreload()
07-01 21:43:47.523 282 282 V Zygote64Timing: BeginPreload took to complete: 112ms
07-01 21:43:47.524 282 282 I Zygote : Preloading classes...
07-01 21:43:47.745 283 283 V Zygote32Timing: PostZygoteInitGC took to complete: 330ms
07-01 21:43:47.745 283 283 V Zygote32Timing: ZygoteInit took to complete: 377ms
07-01 21:43:47.748 283 283 I Zygote : Accepting command socket connections
07-01 21:43:48.888 282 282 I Zygote : ...preloaded 17308 classes in 1364ms.
07-01 21:43:48.897 282 282 I Zygote : Preloading resources...
07-01 21:43:48.933 282 282 V Zygote64Timing: PreloadResources took to complete: 36ms
07-01 21:43:48.939 282 282 I Zygote : Preloading shared libraries...
07-01 21:43:48.942 282 282 I Zygote : Called ZygoteHooks.endPreload()
07-01 21:43:48.946 282 282 D Zygote : end preload
07-01 21:43:48.946 282 282 V Zygote64Timing: ZygotePreload took to complete: 1535ms
07-01 21:43:49.179 282 282 V Zygote64Timing: PostZygoteInitGC took to complete: 233ms
07-01 21:43:49.179 282 282 V Zygote64Timing: ZygoteInit took to complete: 1810ms
07-01 21:43:49.437 282 282 D Zygote : Forked child process 481
07-01 21:43:49.437 282 282 I Zygote : System server process 481 has been created
07-01 21:43:49.437 282 282 I Zygote : Accepting command socket connections
07-01 21:43:51.624 481 540 D SystemServerTimingAsync: InitThreadPoolExec:SecondaryZygotePreload
07-01 21:43:51.624 481 540 D SystemServerInitThreadPool: Started executing SecondaryZygotePreload
07-01 21:43:51.625 481 540 I SystemServer: SecondaryZygotePreload
07-01 21:43:51.627 283 283 I Zygote : Lazily preloading resources.
07-01 21:43:53.572 481 540 D SystemServerInitThreadPool: Finished executing SecondaryZygotePreload
07-01 21:43:54.078 282 282 I Zygote : Entering forkRepeatedly native zygote loop
07-01 21:43:54.081 282 282 D Zygote : Forked child process 690
结合日志与源码分析
通过上面日志看到,首先通过 init.zygote64.rc 启动 app_process64
那 app_process64 在哪呢,参见如下
# frameworks/base/cmds/app_process/Android.bp
cc_binary {name: "app_process",srcs: ["app_main.cpp"],
}
app_main.cpp 主函数如下
// frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// ...if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);}
}class AppRuntime : public AndroidRuntime { }// ./frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){// 启动虚拟机if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {return;}if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}// ...// 启动 ./frameworks/base/core/java/com/android/internal/os/ZygoteInit.javajmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
}
//./framework/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {if (!enableLazyPreload) {// 加载资源 preload(bootTimingsTraceLog);}// ... // new ZygoteServer 构造中 通过 Zygote.createManagedSocketFromInitSocket 创建 LocalServerSocket zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}}// 创建 sokect server 等待连接caller = zygoteServer.runSelectLoop(abiList);
}
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {// ...pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);// ...
}
// ./framework/base/core/java/com/android/internal/os/Zygote.javastatic int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {ZygoteHooks.preFork();int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);// Set the Java Language thread priority to the default value for new apps.Thread.currentThread().setPriority(Thread.NORM_PRIORITY);ZygoteHooks.postForkCommon();return pid;}
// framework/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(...){pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true);if (pid == 0) {// System server prcoess does not need data isolation so no need to// know pkg_data_info_list.SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,false, nullptr, nullptr, /* is_top_app= */ false,/* pkg_data_info_list */ nullptr,/* allowlisted_data_info_list */ nullptr, false, false);}
}
//./framework/base/core/jni/com_android_internal_os_Zygote.cpp
pid_t zygote::ForkCommon(...){pid_t pid = fork();if (pid == 0) {if (is_priority_fork) {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);} else {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);}}return pid;
}
systemServer zygote创建时序图
通过以上分析,SystemServer 创建对应时序图如下
若显示异常,可以查看图片 https://pic.chenjim.com/202407021035022.png-blog
一般应用 zygote 创建时序图
如果是 system server
以外的进程,会稍微有些不同,时序图如下
若显示异常,可以查看图片 https://pic.chenjim.com/202407022321535.png-blog
向 zygote socket 发送数据时序图
向 zygote socket server 发送数据的时序是怎样的呢,如下图所示
若显示异常,可以查看图片 https://pic.chenjim.com/202407031312243.png-blog
日志中 481 是 system server 进程,690 是 systemui 进程,后续会进一步分析相关流程
相关链接
- Git配置和常用命令
- 安卓软件开发常用命令集合
- adb常用命令详解–提升开发效率利器
- 安卓Framework开发快速分析日志及定位源码