init、zygote、system_server、watchdog分析

1. init初始化

// 代码位于: system/core/init/main.cpp
int main(int argc, char** argv) {
    // 省略部分代码;
    // Boost prio which will be restored later
    setpriority(PRIO_PROCESS, 0, -20);
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();

            return SubcontextMain(argc, argv, &function_map);
        }

        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }

        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }

    return FirstStageMain(argc, argv);
}

1.1 FirstStageMain(第一启动阶段)

system/core/init/first_stage_init.cpp 

        第一阶段主要创建、挂载各种节点(文件/目录),并启动“selinux_setup”。

        (1). 设置PATH(shell)的默认搜索路径:

/** Default shell search path. */
#define _PATH_DEFPATH "/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"

         (2). 将tmpfs挂载到"/dev"目录

// https://man7.org/linux/man-pages/man2/mount.2.html
int mount(const char *source, const char *target,
    const char *filesystemtype, unsigned long mountflags,
    const void *_Nullable data);

/**
 * tmpfs 是一种特殊的文件系统,它存在于计算机的内存中,而不是硬盘或其他持久性存储介质上。
 * 它通常用于存储临时数据,比如系统运行时的临时文件、缓存数据等。
 * tmpfs 文件系统的优点是速度快,因为它直接使用内存,而不需要进行磁盘读写操作。
 * 缺点是存储的数据在系统关机或重启时会丢失,因为它只存在于内存中。
 */
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mkdir("/dev/dm-user", 0755);

mount("devpts", "/dev/pts", "devpts", 0, NULL);

/**
 * proc 是一个特殊的虚拟文件系统,在 Linux 和类 Unix 系统中非常重要。
 * 它主要用于向用户和系统提供关于正在运行的进程和系统状态的信息。
 * 在 Linux 中,proc 文件系统不存储在硬盘上,而是由内核动态生成的。它提供了一种将内核数据结构暴露给用户空间的方法。
 * 通过 proc 文件系统,用户和系统工具可以访问和修改各种系统参数和状态,比如进程信息、内存使用情况、硬件信息等。
 * /proc/cpuinfo 提供了 CPU 的信息,/proc/meminfo 提供了内存的信息,/proc/<PID> 提供了特定进程的信息等。
 */
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);


// https://man7.org/linux/man-pages/man2/mknod.2.html
// int mknod(const char *pathname, mode_t mode, dev_t dev);
// 创建字符型设备节点
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2));
mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3));

mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
    "mode=0755,uid=0,gid=1000");

mkdir("/mnt/vendor", 0755);
mkdir("/mnt/product", 0755);

mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
    "mode=0755,uid=0,gid=0");
mount("tmpfs", "/second_stage_resources", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
    "mode=0755,uid=0,gid=0");

        (3). 重定向标准std::in/std::out/std::error信息

SetStdioToDevNull(argv);

        (4). 转SeLinux阶段

const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
execv(path, const_cast<char**>(args));

1.2 设置SeLinux阶段

        配置SeLinux,然后启动“second_stage”,即第二阶段。

// 代码位于: system/core/init/selinux.cpp
void SelinuxSetEnforcement() {
    // 从 "/proc/cmdline" 的数据中找androidboot.selinux字段内容;
    bool kernel_enforcing = (security_getenforce() == 1);
    bool is_enforcing = IsEnforcing();
    if (kernel_enforcing != is_enforcing) {
        // 设置selinux权限
        if (security_setenforce(is_enforcing)) {
            PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false")
                        << ") failed";
        }
    }
}

const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
execv(path, const_cast<char**>(args));

1.3 SecondStageMain(第二启动阶段)

int SecondStageMain(int argc, char** argv) {
    // 省略部分代码;

    // Now set up SELinux for second stage.
    SelabelInitialize();
    SelinuxRestoreContext();

    Epoll epoll;
    if (auto result = epoll.Open(); !result.ok()) {
        PLOG(FATAL) << result.error();
    }

    // 省略部分代码
    SetUsbController(); //设置sys.usb.comtroller属性值
    SetKernelVersion();

    /**
     * system/core/init/builtins.cpp
     * GetBuiltinFunctionMap()将init.rc中的class_start/class_stop与 do_class_start()/do_class_stop()对应起来
    */
    const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
    Action::set_function_map(&function_map);

    if (!SetupMountNamespaces()) {
        PLOG(FATAL) << "SetupMountNamespaces failed";
    }

    // /vendor和/odm/
    InitializeSubcontext();

    ActionManager& am = ActionManager::GetInstance();
    ServiceList& sm = ServiceList::GetInstance();

    /**
     * 1. 解析是以 section 为单位;
     * 2. Action和Services会隐式声明一个新部分
     * 3. import关键字不是一个命令,而是它自己的section
     *      ==> 因此SectionParser的索引为: service, on, import
     * 4. 如果存在"ro.boot.init_rc"属性,则解析此属性值;
     * 5. 如果不存在"ro.boot.init_rc"属性,则在下面目录中寻找rc文件
     *      /system/etc/init/hw/init.rc
     *      /system/etc/init
     *      /system_ext/etc/init
     *      /vendor/etc/init
     *      /odm/etc/init
     *      /product/etc/init
     * 6. 在上述目前中解析文件及数据,如:ParseData()
    */
    LoadBootScripts(am, sm);

    // 省略部分代码

    am.QueueEventTrigger("early-init");
    // Trigger all the boot actions to get us started.
    am.QueueEventTrigger("init");

    // Don't mount filesystems or start core system services in charger mode.
    std::string bootmode = GetProperty("ro.bootmode", "");
    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }


    while (true) {
        // 开始执行动作, 比如: class_start()
        if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
            am.ExecuteOneCommand();
        }

        // 省略部分代码;
    }

    return 0;
}

2. Zygote的启动

       service声明一个section,然后am.ExecuteOneCommand()将会执行如下内容。其中,subcontext = nullptr,因此执行最后一条语句。       

Result<void> Command::InvokeFunc(Subcontext* subcontext) const {
    if (subcontext) {
        if (execute_in_subcontext_) {
            return subcontext->Execute(args_);
        }

        auto expanded_args = subcontext->ExpandArgs(args_);
        if (!expanded_args.ok()) {
            return expanded_args.error();
        }
        return RunBuiltinFunction(func_, *expanded_args, subcontext->context());
    }

    return RunBuiltinFunction(func_, args_, kInitContext);
}
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    # NOTE: If the wakelock name here is changed, then also
    # update it in SystemSuspend.cpp
    onrestart write /sys/power/wake_lock zygote_kwl
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart --only-if-running media.tuner
    onrestart restart netd
    onrestart restart wificond
    task_profiles ProcessCapacityHigh MaxPerformance
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

        action.cpp中的 RunBuiltinFunction()接口将会调用“class_start main”,并folk一个进程出来,运行service

// 代码位于: system/core/init/service.cpp
Result<void> Service::Start() {
    // 省略部分代码;
    pid_t pid = -1;
    if (namespaces_.flags) {
        pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
    } else {
        pid = fork();
    }

    if (pid == 0) {
        umask(077);
        cgroups_activated.CloseWriteFd();
        setsid_finished.CloseReadFd();
        // ★
        RunService(descriptors, std::move(cgroups_activated), std::move(setsid_finished));
        _exit(127);
    } else {
        cgroups_activated.CloseReadFd();
        setsid_finished.CloseWriteFd();
    }

    // 省略部分代码;
    NotifyStateChange("running");
    reboot_on_failure.Disable();

    LOG(INFO) << "... started service '" << name_ << "' has pid " << pid_;

    return {};
}

static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
    std::vector<std::string> expanded_args;
    std::vector<char*> c_strings;

    expanded_args.resize(args.size());
    c_strings.push_back(const_cast<char*>(args[0].data()));
    for (std::size_t i = 1; i < args.size(); ++i) {
        auto expanded_arg = ExpandProps(args[i]);
        if (!expanded_arg.ok()) {
            LOG(FATAL) << args[0] << ": cannot expand arguments': " << expanded_arg.error();
        }
        expanded_args[i] = *expanded_arg;
        c_strings.push_back(expanded_args[i].data());
    }
    c_strings.push_back(nullptr);

    if (sigstop) {
        kill(getpid(), SIGSTOP);
    }

    return execv(c_strings[0], c_strings.data()) == 0;
}

        然后执行app_process(zygote)流程

// 代码位于: frameworks/base/cmds/app_process/app_main.cpp 
int main(int argc, char* const argv[])
{
    // AppRuntime是AndroidRuntime的子类;
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    // 省略部分代码;

    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        }
        // 省略部分代码;
    }

    Vector<String8> args;
    if (!className.empty()) {
        // 省略部分代码;
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();
        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }
        // 省略部分代码;
    }

	char prop[PROP_VALUE_MAX];
    // ro.product.cpu.abilist64
	if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
		LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
			ABI_LIST_PROPERTY);
		return 11;
	}
	String8 abiFlag("--abi-list=");
	abiFlag.append(prop);    // "--abi-list=arm64-v8a"
	args.add(abiFlag);

    // ★ 
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (!className.empty()) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

***platform:/ # getprop | grep ro.product.cpu.abilist64  
[ro.product.cpu.abilist64]: [arm64-v8a]

        runtime.start()接口将启动JVM虚拟机,注册jni回调函数,反射运行“frameworks/base/core/java/com/android/internal/os/ZygoteInit.java”中的main()的方法。

// 代码位于: frameworks/base/core/jni/AndroidRuntime.cpp
char* AndroidRuntime::toSlashClassName(const char* className)
{
    char* result = strdup(className);
    for (char* cp = result; *cp != '\0'; cp++) {
        if (*cp == '.') {
            *cp = '/';
        }
    }
    return result;
}

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    static const String8 startSystemServer("start-system-server");
    // Whether this is the primary zygote, meaning the zygote which will fork system server.
    bool primary_zygote = false;

    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
            primary_zygote = true;
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        // ★
        env->CallStaticVoidMethod(startClass, startMeth, strArray);
        // 省略部分代码;
    }

}

2.1 ZygoteInit 

    public static void main(String[] argv) {
        ZygoteServer zygoteServer = null;

        Runnable caller;
        try {
            boolean startSystemServer = false;
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } 
                // 省略部分代码;
            }

            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);

            Zygote.initNativeState(isPrimaryZygote);
            zygoteServer = new ZygoteServer(isPrimaryZygote);

            if (startSystemServer) {
                // ★ 
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            // ★ zygote接触消息的线程
            caller = zygoteServer.runSelectLoop(abiList);
        } 

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }

        forkSystemServer()接口中有几个重点项:

        ① --nice-name=system_server, 这个参数将在handleSystemServerProcess(parsedArgs)时设置新folk出来的进程名为:“system_server”;

        ② 调用nativeForkSystemServer接口,调用系统flok()接口,新建system_server进程;

// 代码位于: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 

private static Runnable forkSystemServer(String abiList, String socketName,
		ZygoteServer zygoteServer) {
    // 省略部分代码;
	/* 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,1023,"
					+ "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
			"--capabilities=" + capabilities + "," + capabilities,
			"--nice-name=system_server",
			"--runtime-args",
			"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
			"com.android.server.SystemServer",
	};
	ZygoteArguments parsedArgs;

	int pid;

	try {
		ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
		try {
			parsedArgs = ZygoteArguments.getInstance(commandBuffer);
		} 
        // 省略部分代码;
        /* Request to fork the system server process */
		pid = Zygote.forkSystemServer(
				parsedArgs.mUid, parsedArgs.mGid,
				parsedArgs.mGids,
				parsedArgs.mRuntimeFlags,
				null,
				parsedArgs.mPermittedCapabilities,
				parsedArgs.mEffectiveCapabilities);
	} catch (IllegalArgumentException ex) {
		throw new RuntimeException(ex);
	}

	/* For child process */
	if (pid == 0) {
		if (hasSecondZygote(abiList)) {
			waitForSecondaryZygote(socketName);
		}

		zygoteServer.closeServerSocket();
		return handleSystemServerProcess(parsedArgs);
	}

	return null;
}

        ③ 调用handleSystemServerProcess(parsedArgs),启动SystemServer的main()函数;

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    // 设置进程号名称为: system_server
	if (parsedArgs.mNiceName != null) {
		Process.setArgV0(parsedArgs.mNiceName);
	}

	final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
	if (systemServerClasspath != null) {
		// Capturing profiles is only supported for debug or eng builds since selinux normally
		// prevents it.
		if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
			try {
				Log.d(TAG, "Preparing system server profile");
				final String standaloneSystemServerJars =
						Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
				final String systemServerPaths = standaloneSystemServerJars != null
						? String.join(":", systemServerClasspath, standaloneSystemServerJars)
						: systemServerClasspath;
				prepareSystemServerProfile(systemServerPaths);
			} catch (Exception e) {
				Log.wtf(TAG, "Failed to set up system server profile", e);
			}
		}
	}

    // 省略部分代码;
    ClassLoader cl = getOrCreateSystemServerClassLoader();
	if (cl != null) {
		Thread.currentThread().setContextClassLoader(cl);
	}

	/*
	* Pass the remaining arguments to SystemServer.
	*/
	return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
			parsedArgs.mDisabledCompatChanges,
			parsedArgs.mRemainingArgs, cl);


	/* should never reach here */
}

        而这个函数会调用RuntimeInit::applicationInit()方法,并通过反射调用com.android.server.SystemServer的main()方法;

// 代码位于: frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
		String[] argv, ClassLoader classLoader) {

	// 决定了args.startClass为“com.android.server.SystemServer”
	final Arguments args = new Arguments(argv);

	// Remaining arguments are passed to the start class's static main
	return findStaticMain(args.startClass, args.startArgs, classLoader);
}

3. SystemServer启动

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
	new SystemServer().run();
}

        run()方法中主要执行:

                ①. 设置时区及时间;

                ②. 设置binder最大线程数,主线程分支的时间阀值;

                ③. 实例化systemContext,即ContextImpl实例化

// 代码位于: frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
    // 省略部分代码;

    // Initialize the system context.
	createSystemContext();
}

private void createSystemContext() {
	ActivityThread activityThread = ActivityThread.systemMain();
	mSystemContext = activityThread.getSystemContext();
    // 省略部分代码;
}

// 代码位于: frameworks/base/core/java/android/app/ActivityThread.java
public ContextImpl getSystemContext() {
	synchronized (this) {
		if (mSystemContext == null) {
			mSystemContext = ContextImpl.createSystemContext(this);
		}
		return mSystemContext;
	}
}


// 代码位于: frameworks/base/core/java/android/app/ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) {
	LoadedApk packageInfo = new LoadedApk(mainThread);
	ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
			ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
    // 省略部分代码;
	return context;
}

                ④. 初始化Telephoney、MediaFramework、BT、NFC的ServiceManager;

                ⑤. 实例化SystemServiceManager

                ⑥. 启动其他重要服务;   

        见附件;

4. Watchdog分析

           在SystemServer中,通过对Watchgos的单例创建、初始化等,最后调用Watchdog::run()方法,

private void run() {
    boolean waitedHalf = false;

    while (true) {
        // 省略部分代码
        synchronized (mLock) {
            long timeout = checkIntervalMillis;
            // Make sure we (re)spin the checkers that have become idle within
            // this wait-and-check interval
            for (int i=0; i<mHandlerCheckers.size(); i++) {
                HandlerCheckerAndTimeout hc = mHandlerCheckers.get(i);
                // We pick the watchdog to apply every time we reschedule the checkers. The
                // default timeout might have changed since the last run.
                hc.checker().scheduleCheckLocked(hc.customTimeoutMillis()
                        .orElse(watchdogTimeoutMillis * Build.HW_TIMEOUT_MULTIPLIER));
            }
            
            // 省略部分代码
            while (timeout > 0) {
                try {
                    mLock.wait(timeout);
                    // Note: mHandlerCheckers and mMonitorChecker may have changed after waiting
                } catch (InterruptedException e) {
                    Log.wtf(TAG, e);
                }
                
                timeout = checkIntervalMillis - (SystemClock.uptimeMillis() - start);
            }

            /**
             * 检测状态,而这个状态是通过 Looper-Handler 机制,最后调用 HandlerChecker::run() 来实现; ---> 状态为: COMPLETED
             * private static final boolean DB = false;
             * private static final long DEFAULT_TIMEOUT = DB ? 10 * 1000 : 60 * 1000;  ===> 60s
             * 
             * 小于15s             ----> 状态为: WAITING
             * 大于15秒,小于60s    ----> 状态为:WAITED_UNTIL_PRE_WATCHDOG
             * 大于60s, 重启systenserver
             */
            // 
            final int waitState = evaluateCheckerCompletionLocked();
            if (waitState == COMPLETED) {
                // The monitors have returned; reset
                waitedHalf = false;
                continue;
            } else if (waitState == WAITING) {
                // still waiting but within their configured intervals; back off and recheck
                continue;
            } else if (waitState == WAITED_UNTIL_PRE_WATCHDOG) {
                if (!waitedHalf) {
                    Slog.i(TAG, "WAITED_UNTIL_PRE_WATCHDOG");
                    waitedHalf = true;
                    // We've waited until the pre-watchdog, but we'd need to do the stack trace
                    // dump w/o the lock.
                    blockedCheckers = getCheckersWithStateLocked(WAITED_UNTIL_PRE_WATCHDOG);
                    subject = describeCheckersLocked(blockedCheckers);
                    pids = new ArrayList<>(mInterestingJavaPids);
                    doWaitedPreDump = true;
                } else {
                    continue;
                }
            } else {
                // something is overdue!
                blockedCheckers = getCheckersWithStateLocked(OVERDUE);
                subject = describeCheckersLocked(blockedCheckers);
                allowRestart = mAllowRestart;
                pids = new ArrayList<>(mInterestingJavaPids);
            }
        } // END synchronized (mLock)

        // If we got here, that means that the system is most likely hung.
        //
        // First collect stack traces from all threads of the system process.
        //
        // Then, if we reached the full timeout, kill this process so that the system will
        // restart. If we reached pre-watchdog timeout, just log some information and continue.
        logWatchog(doWaitedPreDump, subject, pids);

        if (doWaitedPreDump) {
            // We have waited for only pre-watchdog timeout, we continue to wait for the
            // duration of the full timeout before killing the process.
            continue;
        }

        IActivityController controller;
        synchronized (mLock) {
            controller = mController;
        }
        if (controller != null) {
            Slog.i(TAG, "Reporting stuck state to activity controller");
            try {
                Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
                // 1 = keep waiting, -1 = kill system
                int res = controller.systemNotResponding(subject);
                if (res >= 0) {
                    Slog.i(TAG, "Activity controller requested to coninue to wait");
                    waitedHalf = false;
                    continue;
                }
            } catch (RemoteException e) {
            }
        }

        // Only kill the process if the debugger is not attached.
        if (Debug.isDebuggerConnected()) {
            debuggerWasConnected = 2;
        }
        if (debuggerWasConnected >= 2) {
            Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
        } else if (debuggerWasConnected > 0) {
            Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
        } else if (!allowRestart) {
            Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
        } else {
            Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
            WatchdogDiagnostics.diagnoseCheckers(blockedCheckers);
            Slog.w(TAG, "*** GOODBYE!");
            if (!Build.IS_USER && isCrashLoopFound()
                    && !WatchdogProperties.should_ignore_fatal_count().orElse(false)) {
                breakCrashLoop();
            }
            Process.killProcess(Process.myPid());
            System.exit(10);
        }

        waitedHalf = false;
    }
}

        Watchdog主要监听以下服务:

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值