安卓14中Zygote初始化流程及源码分析

news2024/11/15 13:25:56

文章目录

    • 日志抓取
    • 结合日志与源码分析
    • 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.java
    jmethodID 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.java
 static 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 创建对应时序图如下

init.cpp init.zygote64.rc app_process.cpp AndroidRuntime.cpp ZygoteInit.java Zygote.java os_Zygote.cpp ZygoteServer.java LoadBootScripts service zygote start(...) startVm(...) startReg(...) main(...) preload(...) forkSystemServer(...) forkSystemServer(...) nativeForkSystemServer(...) zygote::ForkCommon(...) SpecializeCommon(...) new ZygoteServer(...) createManagedSocketFromInitSocket(...) runSelectLoop(...) init.cpp init.zygote64.rc app_process.cpp AndroidRuntime.cpp ZygoteInit.java Zygote.java os_Zygote.cpp ZygoteServer.java

若显示异常,可以查看图片 https://pic.chenjim.com/202407021035022.png-blog

一般应用 zygote 创建时序图

如果是 system server 以外的进程,会稍微有些不同,时序图如下

ZygoteServer.java ZygoteConnection.java Zygote.java ZygoteCommandBuffer.java ZygoteCommandBuffer.cpp os_Zygote.cpp runSelectLoop(...) processCommand(...) forkSimpleApps(...) forkRepeatedly(...) nativeForkRepeatedly(...) zygote::forkApp(...) zygote::ForkCommon(...) ZygoteServer.java ZygoteConnection.java Zygote.java ZygoteCommandBuffer.java ZygoteCommandBuffer.cpp os_Zygote.cpp

若显示异常,可以查看图片 https://pic.chenjim.com/202407022321535.png-blog

向 zygote socket 发送数据时序图

向 zygote socket server 发送数据的时序是怎样的呢,如下图所示

ActivityManagerService.java ProcessList.java Process.java ZygoteProcess.java startProcessLocked(...) startProcessLocked(...) handleProcessStart(...) startProcess(...) start(...) start(...) startViaZygote(...) zygoteSendArgsAndGetResult(...) attemptZygoteSendArgsAndGetResult(...) ActivityManagerService.java ProcessList.java Process.java ZygoteProcess.java

若显示异常,可以查看图片 https://pic.chenjim.com/202407031312243.png-blog


日志中 481 是 system server 进程,690 是 systemui 进程,后续会进一步分析相关流程


相关链接

  • Git配置和常用命令
  • 安卓软件开发常用命令集合
  • adb常用命令详解–提升开发效率利器
  • 安卓Framework开发快速分析日志及定位源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1922583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

抗量子密码算法:保障未来信息安全的新盾牌

随着量子计算的迅猛发展&#xff0c;传统加密算法正面临着前所未有的挑战。量子计算机利用量子比特的特殊性质&#xff0c;能在极短时间内破解目前广泛使用的公钥加密体系&#xff0c;如RSA、ECC等。这使得我国及全球的信息安全体系遭受严重威胁。为了应对这一挑战&#xff0c;…

知识图谱入门笔记

自学参考&#xff1a; 视频&#xff1a;斯坦福CS520 | 知识图谱 最全知识图谱综述 详解知识图谱的构建全流程 知识图谱构建&#xff08;概念&#xff0c;工具&#xff0c;实例调研&#xff09; 一、基本概念 知识图谱&#xff08;Knowledge graph&#xff09;&#xff1a;由结…

基于LSTM的局部特征提取网络算法原理

目录 一、LSTM的基本原理与结构 1. LSTM的核心结构 2. LSTM的工作原理 二、基于LSTM的局部特征提取 1. 输入处理与序列表示 2. LSTM层处理与特征提取 3. 特征提取的优势与应用 三、实现细节与注意事项 1. 数据预处理 2. 网络结构与参数选择 3. 训练策略与正则化 4.…

Chapter 1:数据结构前言

在数字化的世界里&#xff0c;我们每天都在与数据打交道。然而&#xff0c;你是否曾想过&#xff0c;这些数据是如何被组织、存储和处理的&#xff1f;这就是数据结构的魅力所在。 数据结构&#xff0c;简单来说&#xff0c;就是数据的组织方式。它决定了我们如何高效地访问和操…

【游戏客户端】大话slg玩法架构(三)建筑控件

【游戏客户端】大话slg玩法架构&#xff08;三&#xff09;建筑控件 大家好&#xff0c;我是Lampard家杰~~ 今天我们继续给大家分享SLG玩法的实现架构&#xff0c;关于SLG玩法的介绍可以参考这篇上一篇文章&#xff1a;【游戏客户端】制作率土之滨Like玩法 PS&#xff1a;和之前…

JVM系列 | 垃圾收集算法

JVM系列 | 垃圾收集算法 文章目录 前言如何判断对象已"死"&#xff1f;引用计数法可达性分析算法可达性分析2.0版 | 引用的增强对象的消亡过程回收方法区主要回收目标&#xff1a;回收操作 垃圾收集算法分代收集理论 与 跨代引用假说分代收集理论跨带引用假说 垃圾收…

Oracle数据库加密与安全

Wallet简介&#xff1a; Oracle Wallet(即内部加密技术TDE( Transparent DataEncryption&#xff09; TDE是 Oracle10gR2中推出的一个新功能,使用时要保证Oracle版本是在10gR2或者以上 Wallet配置&#xff1a; 1.创建一个新目录&#xff0c;并指定为Wallet目录 /home/oracle…

论文翻译:Large Language Models for Education: A Survey and Outlook

https://arxiv.org/abs/2403.18105 目录 教育领域的大型语言模型&#xff1a;一项调查和展望摘要1. 引言2. 教育应用中的LLM2.1 概述2.2 学习辅助2.2.1 问题解决&#xff08;QS&#xff09; 2.2.2 错误纠正&#xff08;EC&#xff09;2.2.3 困惑助手&#xff08;CH&#xff09;…

ExcelToDB2:批量导入Excel到IBM DB2数据库的自动化工具

ExcelToDB2&#xff1a;批量导入Excel到IBM DB2数据库的自动化工具 简介 ExcelToDB2是一个可以批量导入Excel到IBM DB2数据库的自动化工具。支持将xls/xlsx/xlsm/xlsb/csv/txt/xml格式的Excel文件导入到IBM DB2等多种原生及国产数据库。自动化是其最大的特点&#xff0c;因为它…

Python爬虫教程第5篇-使用BeautifulSoup查找html元素几种常用方法

文章目录 简介find()和find_all()字符串通过id查找通过属性查找通过.方式查找通过CSS选择器查找通过xpath查找正则表达自定义方法总结 简介 上一篇详细的介绍了如何使用Beautiful Soup的使用方法&#xff0c;但是最常用的还是如何解析html元素&#xff0c;这里再汇总介绍下查询…

数据分析——Python网络爬虫(四){正则表达式}

爬虫库的使用 爬虫的步骤正则表达式正则表达式的流程正则表达式的使用括号的使用管道匹配问号匹配星号匹配加号匹配花括号匹配用点-星匹配所有字符跨行匹配findall方法其他常用字符匹配 例子正则表达式在线测试 爬虫的步骤 #mermaid-svg-zSQSbTxUEex051NQ {font-family:"t…

Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;控制大图和遮罩层的显隐性 &#xff08;3&#xff09;遮罩层跟随鼠标移动 &…

【电脑应用技巧】如何寻找电脑应用的安装包华为电脑、平板和手机资源交换共享

电脑的初学者可能会直接用【百度】搜索电脑应用程序的安装包&#xff0c;但是这样找到的电脑应用程序安装包经常会被加入木马或者强制捆绑一些不需要的应用装入电脑。 今天告诉大家一个得到干净电脑应用程序安装包的方法&#xff0c;就是用【联想的应用商店】。联想电脑我是一点…

使用Lego进行证书的申请和更新

姊妹篇: 使用Let’s Encrypt 申请通配符证书 关于acme 协议 ACME是自动证书管理环境&#xff08;Automatic Certificate Management Environment&#xff09;的缩写&#xff0c;是一个由IETF&#xff08;Internet Engineering Task Force&#xff09;制定的协议标准&#xff0c…

gd32F470串口重定义

c代码&#xff1a; /** Author: Bleaach008* Date: 2024-07-10 17:31:01* LastEditTime: 2024-07-11 09:42:06* FilePath: \MDK-ARMd:\Code\GD32\GD01_UART\MyApplication\Public.c* Description:** Copyright (c) 2024 by 008, All Rights Reserved.*/ /* Includes ----------…

QFileDialog的简单了解

ps&#xff1a;写了点垃圾&#xff08;哈哈哈&#xff09; 现在感觉Qt库应该是调用了Windows提供的这块的接口了。 它继承自QDialog 这是Windows自己的文件夹 这是两者的对比图&#xff1a; 通过看QFileDialog的源码&#xff0c;来分析它是怎么实现这样的效果的。 源码组成…

面试篇-Java-5+设计模式

文章目录 前言一、你知道工厂方法模式吗1.1 你有使用过简单工厂模式吗1.2 你有使用过简单工厂方法模式吗1.3 你有使用过抽象工厂方法模式吗1.4 你有使用过策略模式吗 二、你们项目中是怎么使用设计模式的呢2.1 策略模式 工厂模式 实现不同的方式的登录2.1.1 定义一个登录的接口…

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测 目录 SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现NGO-CNN-LSTM-Mutilhead-Attention北方苍鹰算…

怎么用PPT录制微课?详细步骤解析!

随着信息技术的不断发展&#xff0c;微课作为一种新型的教学形式&#xff0c;因其短小精悍、针对性强等特点&#xff0c;在教育领域得到了广泛的应用。而PPT作为一款常用的演示工具&#xff0c;不仅可以用来制作课件&#xff0c;还可以利用其内置的录屏功能或结合专业的录屏软件…

【机器学习】Exam4

实现线性不可分logistic逻辑回归 我们目前所学的都是线性回归&#xff0c;例如 y w 1 x 1 w 2 x 2 b y w_1x_1w_2x_2b yw1​x1​w2​x2​b 用肉眼来看数据集的话不难发现&#xff0c;线性回归没有用了&#xff0c;那么根据课程所学&#xff0c;我们是不是可以增加 x 3 x…