-
-
[原创]chromium 的启动
-
发表于: 2025-11-4 21:07 1146
-
简单串一下浏览器启动的整个流程. 这样可以将 chromium 的框架串起来, 作者志大才疏, 有写的不好地方还请指出.
Chromium 的入口文件设计是不同系统有各自的入口文件, 最终都会汇总到统一的核心启动逻辑:
这个最短:
该文件仅用于 Linux 等类 Unix 系统, 是基于 Aura 界面框架的入口实现, 其核心是直接调用 ChromeMain(argc, argv), 无需中间 DLL 加载层, 与 Windows 需通过 chrome.dll 启动的逻辑完全不同.
贴出主要部分:
主要是在通过 dlopen 动态加载框架, 从加载的框架中查找并调用 ChromeMain 函数, 传入命令行参数, 最终通过 exit 退出以保证栈回溯完整性
只贴出主要的 main 函数:
初始化命令行, 设置工作目录, 各种奔溃处理..., 实际上是 loader->Launch 在进一步加载, 进入 chrome\app\main_dll_loader_win.cc:
仍然是用进入 ChromeMain 函数.
又是各种乱七八糟的不同平台的参数处理, 初始化等等, 值得注意的是在这里处理了无头模式, 然后调用 ContentMain 进一步启动, 来到 content\public\app\content_main.h:
在跟入默认实现 content\app\content_main.cc:
又是初始化一堆, 接着跟入 content_main_runner->Run, 来到 content\app\content_main_runner_impl.cc:
主进程启动时不携带 --type 参数, 则 process_type.empty() 是 true, 所以我们先不管子进程, 也就是 if (!process_type.empty()) 中的逻辑.
注册一下这三种进程的回调类:
这段代码, 初始化了 Mojo, 用于进程通信, 然后又初始化一大堆, 可以自己读读. 在跟入 RunBrowserProcessMain:
delegate->RunProcess 对一些平台做了些处理, 不太重要, 继续跟入 BrowserMain, 来到 content\browser\browser_main.cc:
这个就是生命周期控制函数,
首先看下 main_runner->Initialize, 跟入, 来到 content\browser\browser_main_runner_impl.cc:
可以看到这里初始化一大堆, 什么 ui, font, skia..., 再跟入 main_runner->Run:
在跟入 RunMainMessageLoop:
不管三七二十一, 跟入 main_run_loop->Run, 来到了 base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:
在跟入 pump_->Run, 发现不同平台还是有不同的实现:

我们看 base\message_loop\message_pump_default.cc 中的:
大体上就是一套任务队列机制, 所有任务(UI 事件, 网络回调, 延迟任务, 空闲任务等)最终都会被放入任务队列中, 消息泵循环的核心就是"从队列取任务→执行→再取"的循环, 这是整套机制的底层基础.
回到最开始 ContentMainRunnerImpl::Run, 还记得有一个主进程子进程的分流吗, 我们从这里开始看, 跟人 RunOtherNamedProcessTypeMain 来到 content\app\content_main_runner_impl.cc:
一个个来看.
仍然是启动子进程加入消息队列. 等待主进程派发任务.
好了, 到此为止吧.
#include "build/build_config.h"extern "C" {int ChromeMain(int argc, const char** argv);}int main(int argc, const char** argv) { return ChromeMain(argc, argv);}#include "build/build_config.h"extern "C" {int ChromeMain(int argc, const char** argv);}int main(int argc, const char** argv) { return ChromeMain(argc, argv);}// 定义对外可见的main函数, 作为程序入口点// 参数: argc - 命令行参数数量; argv - 命令行参数数组__attribute__((visibility("default"))) int main(int argc, char* argv[]) { // 早期注册PartitionAlloc内存分配器的malloc区域(初始化内存分配器) partition_alloc::EarlyMallocZoneRegistration(); uint32_t exec_path_size = 0; // 用于存储可执行文件路径的长度 // 第一次调用_NSGetExecutablePath获取路径长度(传入NULL时仅返回所需长度) int rv = _NSGetExecutablePath(NULL, &exec_path_size); if (rv != -1) { // 正常情况下应返回-1(表示需要分配缓冲区), 否则报错 FatalError("_NSGetExecutablePath: get length failed."); } // 根据获取的长度分配缓冲区存储可执行文件路径 std::unique_ptr<char[]> exec_path(new char[exec_path_size]); // 第二次调用_NSGetExecutablePath获取实际路径 rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size); if (rv != 0) { // 返回0表示成功, 非0则路径获取失败 FatalError("_NSGetExecutablePath: get path failed."); }#if defined(HELPER_EXECUTABLE) // 如果是辅助可执行程序(Helper) // 创建沙箱服务端并解析启动参数(macOS沙箱机制) sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt = sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc, argv); if (seatbelt.sandbox_required) { // 如果需要启用沙箱 if (!seatbelt.server) { // 沙箱服务端创建失败 FatalError("Failed to create seatbelt sandbox server."); } if (!seatbelt.server->InitializeSandbox()) { // 沙箱初始化失败 FatalError("Failed to initialize sandbox."); } } // 辅助程序位于版本化框架目录中, 通过相对路径定位主框架 const char rel_path[] = "../../../../" PRODUCT_FULLNAME_STRING " Framework";#else // 非辅助程序(主程序) // 主程序通过相对路径定位框架(版本化路径, 包含版本号) const char rel_path[] = "../Frameworks/" PRODUCT_FULLNAME_STRING " Framework.framework/Versions/" CHROME_VERSION_STRING "/" PRODUCT_FULLNAME_STRING " Framework";#endif // defined(HELPER_EXECUTABLE) // 从可执行文件路径中提取父目录, 拼接相对路径得到框架完整路径 const char* parent_dir = dirname(exec_path.get()); // 获取父目录路径 if (!parent_dir) { // dirname失败(如路径无效) FatalError("dirname %s: %s.", exec_path.get(), strerror(errno)); } // 计算拼接路径所需的缓冲区大小 const size_t parent_dir_len = strlen(parent_dir); // 父目录长度 const size_t rel_path_len = strlen(rel_path); // 相对路径长度 // +2 用于容纳路径分隔符'/'和字符串结束符'\0' const size_t framework_path_size = parent_dir_len + rel_path_len + 2; // 分配缓冲区存储框架完整路径 std::unique_ptr<char[]> framework_path(new char[framework_path_size]); // 拼接父目录和相对路径, 生成框架的完整路径 snprintf(framework_path.get(), framework_path_size, "%s/%s", parent_dir, rel_path); // 加载框架动态库(RTLD_LAZY: 延迟绑定;RTLD_LOCAL: 符号仅本模块可见;RTLD_FIRST: 优先从该库查找符号) void* library = dlopen(framework_path.get(), RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST); if (!library) { // 动态库加载失败 FatalError("dlopen %s: %s.", framework_path.get(), dlerror()); } // 从加载的动态库中查找"ChromeMain"符号(核心启动函数) const ChromeMainPtr chrome_main = reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain")); if (!chrome_main) { // 未找到ChromeMain函数 FatalError("dlsym ChromeMain: %s.", dlerror()); } // 调用ChromeMain函数, 传入命令行参数, 执行核心启动逻辑 rv = chrome_main(argc, argv); // 使用exit而非return, 避免尾调用优化导致main函数从栈回溯中消失 exit(rv);}// 定义对外可见的main函数, 作为程序入口点// 参数: argc - 命令行参数数量; argv - 命令行参数数组__attribute__((visibility("default"))) int main(int argc, char* argv[]) { // 早期注册PartitionAlloc内存分配器的malloc区域(初始化内存分配器) partition_alloc::EarlyMallocZoneRegistration(); uint32_t exec_path_size = 0; // 用于存储可执行文件路径的长度 // 第一次调用_NSGetExecutablePath获取路径长度(传入NULL时仅返回所需长度) int rv = _NSGetExecutablePath(NULL, &exec_path_size); if (rv != -1) { // 正常情况下应返回-1(表示需要分配缓冲区), 否则报错 FatalError("_NSGetExecutablePath: get length failed."); } // 根据获取的长度分配缓冲区存储可执行文件路径 std::unique_ptr<char[]> exec_path(new char[exec_path_size]); // 第二次调用_NSGetExecutablePath获取实际路径 rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size); if (rv != 0) { // 返回0表示成功, 非0则路径获取失败 FatalError("_NSGetExecutablePath: get path failed."); }#if defined(HELPER_EXECUTABLE) // 如果是辅助可执行程序(Helper) // 创建沙箱服务端并解析启动参数(macOS沙箱机制) sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt = sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc, argv); if (seatbelt.sandbox_required) { // 如果需要启用沙箱 if (!seatbelt.server) { // 沙箱服务端创建失败 FatalError("Failed to create seatbelt sandbox server."); } if (!seatbelt.server->InitializeSandbox()) { // 沙箱初始化失败 FatalError("Failed to initialize sandbox."); } } // 辅助程序位于版本化框架目录中, 通过相对路径定位主框架 const char rel_path[] = "../../../../" PRODUCT_FULLNAME_STRING " Framework";#else // 非辅助程序(主程序) // 主程序通过相对路径定位框架(版本化路径, 包含版本号) const char rel_path[] = "../Frameworks/" PRODUCT_FULLNAME_STRING " Framework.framework/Versions/" CHROME_VERSION_STRING "/" PRODUCT_FULLNAME_STRING " Framework";#endif // defined(HELPER_EXECUTABLE) // 从可执行文件路径中提取父目录, 拼接相对路径得到框架完整路径 const char* parent_dir = dirname(exec_path.get()); // 获取父目录路径 if (!parent_dir) { // dirname失败(如路径无效) FatalError("dirname %s: %s.", exec_path.get(), strerror(errno)); } // 计算拼接路径所需的缓冲区大小 const size_t parent_dir_len = strlen(parent_dir); // 父目录长度 const size_t rel_path_len = strlen(rel_path); // 相对路径长度 // +2 用于容纳路径分隔符'/'和字符串结束符'\0' const size_t framework_path_size = parent_dir_len + rel_path_len + 2; // 分配缓冲区存储框架完整路径 std::unique_ptr<char[]> framework_path(new char[framework_path_size]); // 拼接父目录和相对路径, 生成框架的完整路径 snprintf(framework_path.get(), framework_path_size, "%s/%s", parent_dir, rel_path); // 加载框架动态库(RTLD_LAZY: 延迟绑定;RTLD_LOCAL: 符号仅本模块可见;RTLD_FIRST: 优先从该库查找符号) void* library = dlopen(framework_path.get(), RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST); if (!library) { // 动态库加载失败 FatalError("dlopen %s: %s.", framework_path.get(), dlerror()); } // 从加载的动态库中查找"ChromeMain"符号(核心启动函数) const ChromeMainPtr chrome_main = reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain")); if (!chrome_main) { // 未找到ChromeMain函数 FatalError("dlsym ChromeMain: %s.", dlerror()); } // 调用ChromeMain函数, 传入命令行参数, 执行核心启动逻辑 rv = chrome_main(argc, argv); // 使用exit而非return, 避免尾调用优化导致main函数从栈回溯中消失 exit(rv);}// 根据是否为控制台应用, 选择不同的程序入口函数#if !defined(WIN_CONSOLE_APP)// GUI应用入口:wWinMain(宽字符版本)int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {#else // 控制台应用入口:mainint main() { HINSTANCE instance = GetModuleHandle(nullptr); // 获取当前模块实例句柄#endif // !defined(WIN_CONSOLE_APP)// 32位构建专用:纤程切换逻辑(扩大主线程栈空间)#if defined(ARCH_CPU_32_BITS) enum class FiberStatus { kConvertFailed, kCreateFiberFailed, kSuccess }; FiberStatus fiber_status = FiberStatus::kSuccess; DWORD fiber_error = ERROR_SUCCESS; // 纤程操作失败时的错误码 if (!::IsThreadAFiber()) { // 当前线程未转换为纤程, 执行转换逻辑 constexpr size_t kStackSize = 4 * 1024 * 1024; // 大栈空间大小(4MiB, 对标64位的8MiB) // 将主线程转换为纤程(FIBER_FLAG_FLOAT_SWITCH支持浮点寄存器切换) LPVOID original_fiber = ::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH); if (original_fiber) { FiberState fiber_state = {instance, original_fiber}; // 初始化纤程状态 // 创建大栈纤程, 绑定启动函数FiberBinder和状态参数 LPVOID big_stack_fiber = ::CreateFiberEx( 0, kStackSize, FIBER_FLAG_FLOAT_SWITCH, FiberBinder, &fiber_state); if (big_stack_fiber) { ::SwitchToFiber(big_stack_fiber); // 切换到大栈纤程执行 // 执行完成后清理纤程资源(避免TLS相关的关闭崩溃) ::DeleteFiber(big_stack_fiber); ::ConvertFiberToThread(); return fiber_state.fiber_result; // 返回纤程执行结果 } fiber_status = FiberStatus::kCreateFiberFailed; // 大栈纤程创建失败 } else { fiber_status = FiberStatus::kConvertFailed; // 线程转纤程失败 } // 记录错误码(供崩溃报告分析) fiber_error = ::GetLastError(); base::debug::Alias(&fiber_error); } // 若已为纤程, 直接继续执行#endif // defined(ARCH_CPU_32_BITS) // 1. 设置浏览器进程的工作目录 SetCwdForBrowserProcess(); // 2. 从主模块初始化安装信息(如版本, 渠道) install_static::InitializeFromPrimaryModule(); // 3. 信号通知:初始化崩溃报告机制 SignalInitializeCrashReporting(); // 4. 浏览器进程禁用延迟加载失败钩子(避免启动时钩子干扰) if (IsBrowserProcess()) chrome::DisableDelayLoadFailureHooksForMainExecutable(); // 5. 32位构建:检查纤程切换是否成功, 失败则崩溃#if defined(ARCH_CPU_32_BITS) CHECK_EQ(fiber_status, FiberStatus::kSuccess);#endif // defined(ARCH_CPU_32_BITS) // 启用内存不足时的终止机制(确保OOM错误正确通知系统) base::EnableTerminationOnOutOfMemory(); // 注册Abseil库的崩溃钩子(统一崩溃处理) logging::RegisterAbslAbortHook(); // 初始化命令行单例(从环境变量解析命令行) base::CommandLine::Init(0, nullptr); const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); // 获取进程类型(如浏览器进程, 渲染进程, Crashpad进程等) const std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType);// 非组件构建且启用DCHECK时的特殊处理#if !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 禁用FeatureList的默认访问(避免chrome.exe中未初始化的FeatureList被误访问) base::FeatureList::FailOnFeatureAccessWithoutFeatureList(); // 修补IAT(导入地址表), 检测第三方代码对Chrome句柄的篡改 base::debug::HandleHooks::AddIATPatch(CURRENT_MODULE());#endif // !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 验证非浏览器进程是否包含有效的/prefetch参数(确保预加载正确) DCHECK(process_type.empty() || HasValidWindowsPrefetchArgument(*command_line)); // 分支1:当前为Crashpad崩溃处理进程 if (process_type == crash_reporter::switches::kCrashpadHandler) { std::unique_ptr<ExitCodeWatcher> exit_code_watcher; // 进程退出码监视器 // 初始化备用崩溃处理 crash_reporter::SetupFallbackCrashHandling(*command_line); // 非周期性任务进程(监控浏览器进程, 而非其他Crashpad进程) if (!command_line->HasSwitch("no-periodic-tasks")) { // 从命令行解析初始客户端数据(获取父进程信息) crashpad::InitialClientData initial_client_data; if (initial_client_data.InitializeFromString( command_line->GetSwitchValueASCII("initial-client-data"))) { // 复制父进程句柄(用于监控退出状态) HANDLE duplicate_handle = INVALID_HANDLE_VALUE; if (DuplicateHandle( ::GetCurrentProcess(), initial_client_data.client_process(), ::GetCurrentProcess(), &duplicate_handle, PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS)) { base::Process parent_process(duplicate_handle); // 创建并启动退出码监视器 exit_code_watcher = std::make_unique<ExitCodeWatcher>(); if (exit_code_watcher->Initialize(std::move(parent_process))) { exit_code_watcher->StartWatching(); } } } } // 强制检查命令行是否包含用户数据目录参数(Crashpad必需) DCHECK(command_line->HasSwitch(switches::kUserDataDir)); // 获取用户数据目录, 启动Crashpad处理器 base::FilePath user_data_dir = command_line->GetSwitchValuePath(switches::kUserDataDir); int crashpad_status = crash_reporter::RunAsCrashpadHandler( *base::CommandLine::ForCurrentProcess(), user_data_dir, switches::kProcessType, switches::kUserDataDir); // 若Crashpad初始化失败, 停止监视器以正常退出 if (crashpad_status != 0 && exit_code_watcher) { exit_code_watcher->StopWatching(); } return crashpad_status; } // 分支2:当前为备用崩溃处理进程 else if (process_type == crash_reporter::switches::kFallbackCrashHandler) { return RunFallbackCrashHandler(*command_line); } // 记录程序入口时间戳(用于启动性能分析) const base::TimeTicks exe_entry_point_ticks = base::TimeTicks::Now(); // 信号通知ChromeElf模块:Chrome开始启动(安全模块初始化) SignalChromeElf(); // 初始化退出管理器(负责单例对象的析构) base::AtExitManager exit_manager; // 尝试快速通知已运行的Chrome(单实例逻辑), 成功则直接退出 if (AttemptFastNotify(*command_line)) return 0; // 加载并启动chrome.dll(核心逻辑均在DLL中实现) VLOG(1) << "About to load main DLL."; MainDllLoader* loader = MakeMainDllLoader(); // 创建DLL加载器 // 启动DLL, 传入实例句柄和入口时间戳 int rc = loader->Launch(instance, exe_entry_point_ticks); // 检查是否需要重启Chrome(如版本更新后) loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); delete loader; // 释放加载器资源 // 工具进程(UtilityProcess)直接强制终止(避免关闭时崩溃, 更安全高效) if (process_type == switches::kUtilityProcess) { base::Process::TerminateCurrentProcessImmediately(rc); } return rc; // 返回退出码}// 根据是否为控制台应用, 选择不同的程序入口函数#if !defined(WIN_CONSOLE_APP)// GUI应用入口:wWinMain(宽字符版本)int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {#else // 控制台应用入口:mainint main() { HINSTANCE instance = GetModuleHandle(nullptr); // 获取当前模块实例句柄#endif // !defined(WIN_CONSOLE_APP)// 32位构建专用:纤程切换逻辑(扩大主线程栈空间)#if defined(ARCH_CPU_32_BITS) enum class FiberStatus { kConvertFailed, kCreateFiberFailed, kSuccess }; FiberStatus fiber_status = FiberStatus::kSuccess; DWORD fiber_error = ERROR_SUCCESS; // 纤程操作失败时的错误码 if (!::IsThreadAFiber()) { // 当前线程未转换为纤程, 执行转换逻辑 constexpr size_t kStackSize = 4 * 1024 * 1024; // 大栈空间大小(4MiB, 对标64位的8MiB) // 将主线程转换为纤程(FIBER_FLAG_FLOAT_SWITCH支持浮点寄存器切换) LPVOID original_fiber = ::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH); if (original_fiber) { FiberState fiber_state = {instance, original_fiber}; // 初始化纤程状态 // 创建大栈纤程, 绑定启动函数FiberBinder和状态参数 LPVOID big_stack_fiber = ::CreateFiberEx( 0, kStackSize, FIBER_FLAG_FLOAT_SWITCH, FiberBinder, &fiber_state); if (big_stack_fiber) { ::SwitchToFiber(big_stack_fiber); // 切换到大栈纤程执行 // 执行完成后清理纤程资源(避免TLS相关的关闭崩溃) ::DeleteFiber(big_stack_fiber); ::ConvertFiberToThread(); return fiber_state.fiber_result; // 返回纤程执行结果 } fiber_status = FiberStatus::kCreateFiberFailed; // 大栈纤程创建失败 } else { fiber_status = FiberStatus::kConvertFailed; // 线程转纤程失败 } // 记录错误码(供崩溃报告分析) fiber_error = ::GetLastError(); base::debug::Alias(&fiber_error); } // 若已为纤程, 直接继续执行#endif // defined(ARCH_CPU_32_BITS) // 1. 设置浏览器进程的工作目录 SetCwdForBrowserProcess(); // 2. 从主模块初始化安装信息(如版本, 渠道) install_static::InitializeFromPrimaryModule(); // 3. 信号通知:初始化崩溃报告机制 SignalInitializeCrashReporting(); // 4. 浏览器进程禁用延迟加载失败钩子(避免启动时钩子干扰) if (IsBrowserProcess()) chrome::DisableDelayLoadFailureHooksForMainExecutable(); // 5. 32位构建:检查纤程切换是否成功, 失败则崩溃#if defined(ARCH_CPU_32_BITS) CHECK_EQ(fiber_status, FiberStatus::kSuccess);#endif // defined(ARCH_CPU_32_BITS) // 启用内存不足时的终止机制(确保OOM错误正确通知系统) base::EnableTerminationOnOutOfMemory(); // 注册Abseil库的崩溃钩子(统一崩溃处理) logging::RegisterAbslAbortHook(); // 初始化命令行单例(从环境变量解析命令行) base::CommandLine::Init(0, nullptr); const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); // 获取进程类型(如浏览器进程, 渲染进程, Crashpad进程等) const std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType);// 非组件构建且启用DCHECK时的特殊处理#if !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 禁用FeatureList的默认访问(避免chrome.exe中未初始化的FeatureList被误访问) base::FeatureList::FailOnFeatureAccessWithoutFeatureList(); // 修补IAT(导入地址表), 检测第三方代码对Chrome句柄的篡改 base::debug::HandleHooks::AddIATPatch(CURRENT_MODULE());#endif // !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 验证非浏览器进程是否包含有效的/prefetch参数(确保预加载正确) DCHECK(process_type.empty() || HasValidWindowsPrefetchArgument(*command_line)); // 分支1:当前为Crashpad崩溃处理进程 if (process_type == crash_reporter::switches::kCrashpadHandler) { std::unique_ptr<ExitCodeWatcher> exit_code_watcher; // 进程退出码监视器 // 初始化备用崩溃处理 crash_reporter::SetupFallbackCrashHandling(*command_line); // 非周期性任务进程(监控浏览器进程, 而非其他Crashpad进程) if (!command_line->HasSwitch("no-periodic-tasks")) { // 从命令行解析初始客户端数据(获取父进程信息) crashpad::InitialClientData initial_client_data; if (initial_client_data.InitializeFromString( command_line->GetSwitchValueASCII("initial-client-data"))) { // 复制父进程句柄(用于监控退出状态) HANDLE duplicate_handle = INVALID_HANDLE_VALUE; if (DuplicateHandle( ::GetCurrentProcess(), initial_client_data.client_process(), ::GetCurrentProcess(), &duplicate_handle, PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS)) { base::Process parent_process(duplicate_handle); // 创建并启动退出码监视器 exit_code_watcher = std::make_unique<ExitCodeWatcher>(); if (exit_code_watcher->Initialize(std::move(parent_process))) { exit_code_watcher->StartWatching(); } } } } // 强制检查命令行是否包含用户数据目录参数(Crashpad必需) DCHECK(command_line->HasSwitch(switches::kUserDataDir)); // 获取用户数据目录, 启动Crashpad处理器 base::FilePath user_data_dir = command_line->GetSwitchValuePath(switches::kUserDataDir); int crashpad_status = crash_reporter::RunAsCrashpadHandler( *base::CommandLine::ForCurrentProcess(), user_data_dir, switches::kProcessType, switches::kUserDataDir); // 若Crashpad初始化失败, 停止监视器以正常退出 if (crashpad_status != 0 && exit_code_watcher) { exit_code_watcher->StopWatching(); } return crashpad_status; } // 分支2:当前为备用崩溃处理进程 else if (process_type == crash_reporter::switches::kFallbackCrashHandler) { return RunFallbackCrashHandler(*command_line); } // 记录程序入口时间戳(用于启动性能分析) const base::TimeTicks exe_entry_point_ticks = base::TimeTicks::Now(); // 信号通知ChromeElf模块:Chrome开始启动(安全模块初始化) SignalChromeElf(); // 初始化退出管理器(负责单例对象的析构) base::AtExitManager exit_manager; // 尝试快速通知已运行的Chrome(单实例逻辑), 成功则直接退出 if (AttemptFastNotify(*command_line)) return 0; // 加载并启动chrome.dll(核心逻辑均在DLL中实现) VLOG(1) << "About to load main DLL."; MainDllLoader* loader = MakeMainDllLoader(); // 创建DLL加载器 // 启动DLL, 传入实例句柄和入口时间戳 int rc = loader->Launch(instance, exe_entry_point_ticks); // 检查是否需要重启Chrome(如版本更新后) loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); delete loader; // 释放加载器资源 // 工具进程(UtilityProcess)直接强制终止(避免关闭时崩溃, 更安全高效) if (process_type == switches::kUtilityProcess) { base::Process::TerminateCurrentProcessImmediately(rc); } return rc; // 返回退出码}// 启动逻辑核心:加载对应DLL并调用其入口函数// 派生类可通过重写OnBeforeLaunch回调函数添加自定义逻辑int MainDllLoader::Launch(HINSTANCE instance, base::TimeTicks exe_entry_point_ticks) { // 获取当前进程的命令行对象(用于解析参数) const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess(); // 从命令行读取进程类型(如浏览器进程, 渲染进程等, 空字符串表示浏览器进程) process_type_ = cmd_line.GetSwitchValueASCII(switches::kProcessType); // 初始化沙箱接口信息(默认所有字段为空) sandbox::SandboxInterfaceInfo sandbox_info = {nullptr}; const bool is_browser = process_type_.empty(); // 判断是否为浏览器进程 // 判断是否启用沙箱:通过命令行解析沙箱类型, 非"无沙箱"模式即为启用 // 注:此处不使用IsUnsandboxedSandboxType(), 因该函数依赖尚未初始化的特性标志 const bool is_sandboxed = sandbox::policy::SandboxTypeFromCommandLine(cmd_line) != sandbox::mojom::Sandbox::kNoSandbox; // 浏览器进程或启用沙箱的子进程, 初始化沙箱信息 if (is_browser || is_sandboxed) { // 非沙箱子进程无需初始化沙箱信息, 否则会被误判为沙箱代理(类似浏览器进程) content::InitializeSandboxInfo( &sandbox_info, // 若设置了扩展点禁用, 添加对应沙箱缓解措施;否则为0 IsExtensionPointDisableSet() ? sandbox::MITIGATION_EXTENSION_POINT_DISABLE : 0); } // 记录DLL预读取的开始和结束时间戳(用于性能分析) base::TimeTicks preread_begin_ticks; base::TimeTicks preread_end_ticks; base::FilePath file; // 存储加载的DLL文件路径 // 加载核心DLL(chrome.dll), 传入命令行, 是否为浏览器进程及时间戳参数 dll_ = Load(&file, cmd_line, is_browser, preread_begin_ticks, preread_end_ticks); if (!dll_) // DLL加载失败, 返回"缺失数据"错误码 return CHROME_RESULT_CODE_MISSING_DATA; // 非浏览器进程:设置进程关闭优先级(确保浏览器退出后子进程优先被系统终止) if (!is_browser) { // 浏览器进程默认关闭优先级为0x280, 子进程优先级设为更高(数值更大), 实现"先杀子进程" // SHUTDOWN_NORETRY:关闭时不重试, 避免注销/关机时出现无效标签页 ::SetProcessShutdownParameters(kNonBrowserShutdownPriority - 1, SHUTDOWN_NORETRY); } // 启动前回调:允许派生类注入自定义逻辑(如参数修改, 环境配置) OnBeforeLaunch(process_type_, file); // 从加载的DLL中获取ChromeMain函数地址(DLL的核心入口点) DLL_MAIN chrome_main = reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); // 调用ChromeMain启动核心逻辑, 传入实例句柄, 沙箱信息和时间戳(转换为内部值) int rc = chrome_main(instance, &sandbox_info, exe_entry_point_ticks.ToInternalValue(), preread_begin_ticks.ToInternalValue(), preread_end_ticks.ToInternalValue()); return rc; // 返回ChromeMain的执行结果(退出码)}// 启动逻辑核心:加载对应DLL并调用其入口函数// 派生类可通过重写OnBeforeLaunch回调函数添加自定义逻辑int MainDllLoader::Launch(HINSTANCE instance, base::TimeTicks exe_entry_point_ticks) { // 获取当前进程的命令行对象(用于解析参数) const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess(); // 从命令行读取进程类型(如浏览器进程, 渲染进程等, 空字符串表示浏览器进程) process_type_ = cmd_line.GetSwitchValueASCII(switches::kProcessType); // 初始化沙箱接口信息(默认所有字段为空) sandbox::SandboxInterfaceInfo sandbox_info = {nullptr}; const bool is_browser = process_type_.empty(); // 判断是否为浏览器进程 // 判断是否启用沙箱:通过命令行解析沙箱类型, 非"无沙箱"模式即为启用 // 注:此处不使用IsUnsandboxedSandboxType(), 因该函数依赖尚未初始化的特性标志 const bool is_sandboxed = sandbox::policy::SandboxTypeFromCommandLine(cmd_line) != sandbox::mojom::Sandbox::kNoSandbox; // 浏览器进程或启用沙箱的子进程, 初始化沙箱信息 if (is_browser || is_sandboxed) { // 非沙箱子进程无需初始化沙箱信息, 否则会被误判为沙箱代理(类似浏览器进程) content::InitializeSandboxInfo( &sandbox_info, // 若设置了扩展点禁用, 添加对应沙箱缓解措施;否则为0 IsExtensionPointDisableSet() ? sandbox::MITIGATION_EXTENSION_POINT_DISABLE : 0); } // 记录DLL预读取的开始和结束时间戳(用于性能分析) base::TimeTicks preread_begin_ticks; base::TimeTicks preread_end_ticks; base::FilePath file; // 存储加载的DLL文件路径 // 加载核心DLL(chrome.dll), 传入命令行, 是否为浏览器进程及时间戳参数 dll_ = Load(&file, cmd_line, is_browser, preread_begin_ticks, preread_end_ticks); if (!dll_) // DLL加载失败, 返回"缺失数据"错误码 return CHROME_RESULT_CODE_MISSING_DATA; // 非浏览器进程:设置进程关闭优先级(确保浏览器退出后子进程优先被系统终止) if (!is_browser) { // 浏览器进程默认关闭优先级为0x280, 子进程优先级设为更高(数值更大), 实现"先杀子进程" // SHUTDOWN_NORETRY:关闭时不重试, 避免注销/关机时出现无效标签页 ::SetProcessShutdownParameters(kNonBrowserShutdownPriority - 1, SHUTDOWN_NORETRY); } // 启动前回调:允许派生类注入自定义逻辑(如参数修改, 环境配置) OnBeforeLaunch(process_type_, file); // 从加载的DLL中获取ChromeMain函数地址(DLL的核心入口点) DLL_MAIN chrome_main = reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); // 调用ChromeMain启动核心逻辑, 传入实例句柄, 沙箱信息和时间戳(转换为内部值) int rc = chrome_main(instance, &sandbox_info, exe_entry_point_ticks.ToInternalValue(), preread_begin_ticks.ToInternalValue(), preread_end_ticks.ToInternalValue()); return rc; // 返回ChromeMain的执行结果(退出码)}// 跨平台Chrome核心入口函数:根据操作系统定义不同签名#if BUILDFLAG(IS_WIN) // Windows平台// 导出ChromeMain函数(供exe调用), 参数包含实例句柄, 沙箱信息和时间戳DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance, sandbox::SandboxInterfaceInfo* sandbox_info, int64_t exe_entry_point_ticks, // 程序入口时间戳(内部值) int64_t preread_begin_ticks, // 预读取开始时间戳(内部值) int64_t preread_end_ticks) { // 预读取结束时间戳(内部值)#elif BUILDFLAG(IS_POSIX) // POSIX兼容平台(Linux, macOS等)// 入口函数签名:接收命令行参数int ChromeMain(int argc, const char** argv) {#else#error Unknown platform. // 未识别的平台, 编译报错#endif#if BUILDFLAG(IS_LINUX) // Linux平台专用:可能从可执行文件路径推断Chrome渠道(如稳定版, 测试版) PossiblyDetermineFallbackChromeChannel(argv[0]);#endif#if BUILDFLAG(IS_WIN) // Windows平台初始化逻辑 // 从主模块初始化安装信息(版本, 渠道等) install_static::InitializeFromPrimaryModule(); // 非组件构建且启用DCHECK时:修补IAT(导入地址表), 检测第三方代码篡改Chrome句柄 // 注:exe的IAT修补在chrome_exe_main_win.cc中单独处理#if !defined(COMPONENT_BUILD) && DCHECK_IS_ON() base::debug::HandleHooks::AddIATPatch(CURRENT_MODULE());#endif // !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 构造启动时间戳结构体(将内部值转换为TimeTicks类型) StartupTimestamps timestamps{ base::TimeTicks::FromInternalValue(exe_entry_point_ticks), base::TimeTicks::FromInternalValue(preread_begin_ticks), base::TimeTicks::FromInternalValue(preread_end_ticks)}; // 创建Chrome主委托对象(封装Chrome的启动配置和回调) ChromeMainDelegate chrome_main_delegate(timestamps);#else // 非Windows平台:创建主委托对象, 仅记录程序入口时间戳 ChromeMainDelegate chrome_main_delegate( {.exe_entry_point_ticks = base::TimeTicks::Now()});#endif // 初始化Content模块参数(Content是Chromium的核心内容模块, 传入主委托对象) content::ContentMainParams params(&chrome_main_delegate);#if BUILDFLAG(IS_WIN) // Windows平台专用配置 // 设置进程异常终止时崩溃(正常返回时自动重置该配置) auto crash_on_detach_resetter = base::ScopedClosureRunner( base::BindOnce(&base::win::SetShouldCrashOnProcessDetach, base::win::ShouldCrashOnProcessDetach())); base::win::SetShouldCrashOnProcessDetach(true); // 配置崩溃报告的终止行为(确保崩溃信息完整) base::win::SetAbortBehaviorForCrashReporting(); // 给Content参数赋值:实例句柄和沙箱信息 params.instance = instance; params.sandbox_info = sandbox_info; // 设置无崩溃转储函数(使用chrome_elf模块通过加载时动态链接解析的函数) base::debug::SetDumpWithoutCrashingFunction(&DumpProcessWithoutCrash); // 验证chrome_elf模块与当前chrome.dll版本是否一致, 不一致则触发无崩溃转储 if (install_static::InstallDetails::Get().VersionMismatch()) base::debug::DumpWithoutCrashing();#else // 非Windows平台:给Content参数赋值命令行参数 params.argc = argc; params.argv = argv; // 初始化命令行单例(从参数解析) base::CommandLine::Init(params.argc, params.argv);#endif // BUILDFLAG(IS_WIN) // 初始化命令行单例(若未初始化, 此处兜底) base::CommandLine::Init(0, nullptr); // 获取当前进程的命令行对象([[maybe_unused]]避免未使用警告) [[maybe_unused]] base::CommandLine* command_line( base::CommandLine::ForCurrentProcess());#if BUILDFLAG(IS_WIN) // Windows平台:若命令行带--raise-timer-frequency, 提高定时器中断频率(1ms) if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kRaiseTimerFrequency)) { timeBeginPeriod(1); }#endif#if BUILDFLAG(IS_MAC) // macOS平台:设置Bundle覆盖(处理资源路径等) SetUpBundleOverrides();#endif#if BUILDFLAG(IS_LINUX) // Linux平台:向命令行追加额外参数 AppendExtraArgumentsToCommandLine(command_line);#endif // 初始化泊松分配采样器(用于内存分配采样分析) // 需在主线程栈采样分析器之前初始化, 避免TLS插槽分配导致的重入问题 base::PoissonAllocationSampler::Init(); // 无头模式(Headless)处理:无GUI的Chrome运行模式 std::unique_ptr<headless::HeadlessModeHandle> headless_mode_handle; if (headless::IsHeadlessMode()) { // 检测是否启用无头模式 // 无头模式不支持多个目标参数, 否则报错 if (command_line->GetArgs().size() > 1) { LOG(ERROR) << "Multiple targets are not supported in headless mode."; return CHROME_RESULT_CODE_UNSUPPORTED_PARAM; } // 初始化无头模式, 失败则输出错误并退出 auto init_headless_mode = headless::InitHeadlessMode(); if (!init_headless_mode.has_value()) { LOG(ERROR) << init_headless_mode.error(); return EXIT_FAILURE; } // 保存无头模式句柄(管理无头模式生命周期) headless_mode_handle = std::move(init_headless_mode.value()); } else { // 非无头模式:处理旧版无头模式提示#ifdef ENABLE_OLD_HEADLESS_INFO if (headless::IsOldHeadlessMode()) { ShowOldHeadlessInfoMaybe(command_line); // 显示旧版无头模式提示信息 return EXIT_FAILURE; }#endif // ENABLE_OLD_HEADLESS_INFO }#if BUILDFLAG(IS_MAC) // macOS平台:若辅助程序被系统或第三方应用意外启动, 优雅退出 if (IsHelperAppLaunchedBySystemOrThirdPartyApplication()) { return 0; }#endif // 启动Content模块主逻辑(Chromium核心启动入口), 传入参数并获取返回值 int rv = content::ContentMain(std::move(params)); // 若返回码为正常结果, 统一返回Content模块的正常退出码;否则返回原始返回码 if (IsNormalResultCode(static_cast<ResultCode>(rv))) { return content::RESULT_CODE_NORMAL_EXIT; } return rv;}// 跨平台Chrome核心入口函数:根据操作系统定义不同签名#if BUILDFLAG(IS_WIN) // Windows平台// 导出ChromeMain函数(供exe调用), 参数包含实例句柄, 沙箱信息和时间戳DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance, sandbox::SandboxInterfaceInfo* sandbox_info, int64_t exe_entry_point_ticks, // 程序入口时间戳(内部值) int64_t preread_begin_ticks, // 预读取开始时间戳(内部值) int64_t preread_end_ticks) { // 预读取结束时间戳(内部值)#elif BUILDFLAG(IS_POSIX) // POSIX兼容平台(Linux, macOS等)// 入口函数签名:接收命令行参数int ChromeMain(int argc, const char** argv) {#else#error Unknown platform. // 未识别的平台, 编译报错#endif#if BUILDFLAG(IS_LINUX) // Linux平台专用:可能从可执行文件路径推断Chrome渠道(如稳定版, 测试版) PossiblyDetermineFallbackChromeChannel(argv[0]);#endif#if BUILDFLAG(IS_WIN) // Windows平台初始化逻辑 // 从主模块初始化安装信息(版本, 渠道等) install_static::InitializeFromPrimaryModule(); // 非组件构建且启用DCHECK时:修补IAT(导入地址表), 检测第三方代码篡改Chrome句柄 // 注:exe的IAT修补在chrome_exe_main_win.cc中单独处理#if !defined(COMPONENT_BUILD) && DCHECK_IS_ON() base::debug::HandleHooks::AddIATPatch(CURRENT_MODULE());#endif // !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // 构造启动时间戳结构体(将内部值转换为TimeTicks类型) StartupTimestamps timestamps{ base::TimeTicks::FromInternalValue(exe_entry_point_ticks), base::TimeTicks::FromInternalValue(preread_begin_ticks), base::TimeTicks::FromInternalValue(preread_end_ticks)}; // 创建Chrome主委托对象(封装Chrome的启动配置和回调) ChromeMainDelegate chrome_main_delegate(timestamps);#else // 非Windows平台:创建主委托对象, 仅记录程序入口时间戳 ChromeMainDelegate chrome_main_delegate( {.exe_entry_point_ticks = base::TimeTicks::Now()});#endif // 初始化Content模块参数(Content是Chromium的核心内容模块, 传入主委托对象) content::ContentMainParams params(&chrome_main_delegate);#if BUILDFLAG(IS_WIN) // Windows平台专用配置 // 设置进程异常终止时崩溃(正常返回时自动重置该配置) auto crash_on_detach_resetter = base::ScopedClosureRunner( base::BindOnce(&base::win::SetShouldCrashOnProcessDetach, base::win::ShouldCrashOnProcessDetach())); base::win::SetShouldCrashOnProcessDetach(true); // 配置崩溃报告的终止行为(确保崩溃信息完整) base::win::SetAbortBehaviorForCrashReporting(); // 给Content参数赋值:实例句柄和沙箱信息 params.instance = instance; params.sandbox_info = sandbox_info; // 设置无崩溃转储函数(使用chrome_elf模块通过加载时动态链接解析的函数) base::debug::SetDumpWithoutCrashingFunction(&DumpProcessWithoutCrash); // 验证chrome_elf模块与当前chrome.dll版本是否一致, 不一致则触发无崩溃转储 if (install_static::InstallDetails::Get().VersionMismatch()) base::debug::DumpWithoutCrashing();#else // 非Windows平台:给Content参数赋值命令行参数 params.argc = argc; params.argv = argv; // 初始化命令行单例(从参数解析) base::CommandLine::Init(params.argc, params.argv);#endif // BUILDFLAG(IS_WIN) // 初始化命令行单例(若未初始化, 此处兜底) base::CommandLine::Init(0, nullptr); // 获取当前进程的命令行对象([[maybe_unused]]避免未使用警告) [[maybe_unused]] base::CommandLine* command_line( base::CommandLine::ForCurrentProcess());#if BUILDFLAG(IS_WIN) // Windows平台:若命令行带--raise-timer-frequency, 提高定时器中断频率(1ms) if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kRaiseTimerFrequency)) { timeBeginPeriod(1); }#endif#if BUILDFLAG(IS_MAC) // macOS平台:设置Bundle覆盖(处理资源路径等) SetUpBundleOverrides();#endif#if BUILDFLAG(IS_LINUX) // Linux平台:向命令行追加额外参数 AppendExtraArgumentsToCommandLine(command_line);#endif // 初始化泊松分配采样器(用于内存分配采样分析) // 需在主线程栈采样分析器之前初始化, 避免TLS插槽分配导致的重入问题 base::PoissonAllocationSampler::Init(); // 无头模式(Headless)处理:无GUI的Chrome运行模式 std::unique_ptr<headless::HeadlessModeHandle> headless_mode_handle; if (headless::IsHeadlessMode()) { // 检测是否启用无头模式 // 无头模式不支持多个目标参数, 否则报错 if (command_line->GetArgs().size() > 1) { LOG(ERROR) << "Multiple targets are not supported in headless mode."; return CHROME_RESULT_CODE_UNSUPPORTED_PARAM; } // 初始化无头模式, 失败则输出错误并退出 auto init_headless_mode = headless::InitHeadlessMode(); if (!init_headless_mode.has_value()) { LOG(ERROR) << init_headless_mode.error(); return EXIT_FAILURE; } // 保存无头模式句柄(管理无头模式生命周期) headless_mode_handle = std::move(init_headless_mode.value()); } else { // 非无头模式:处理旧版无头模式提示#ifdef ENABLE_OLD_HEADLESS_INFO if (headless::IsOldHeadlessMode()) { ShowOldHeadlessInfoMaybe(command_line); // 显示旧版无头模式提示信息 return EXIT_FAILURE; }#endif // ENABLE_OLD_HEADLESS_INFO }#if BUILDFLAG(IS_MAC) // macOS平台:若辅助程序被系统或第三方应用意外启动, 优雅退出 if (IsHelperAppLaunchedBySystemOrThirdPartyApplication()) { return 0; }#endif // 启动Content模块主逻辑(Chromium核心启动入口), 传入参数并获取返回值 int rv = content::ContentMain(std::move(params)); // 若返回码为正常结果, 统一返回Content模块的正常退出码;否则返回原始返回码 if (IsNormalResultCode(static_cast<ResultCode>(rv))) { return content::RESULT_CODE_NORMAL_EXIT; } return rv;}#if BUILDFLAG(IS_ANDROID) // Android平台专用声明// 说明:Android平台中, Content模块的启动入口是ContentMain.java(Java层)// 该函数提供了一种方式, 为ContentMainRunner设置ContentMainDelegate委托对象// 调用限制:必须在ContentMainRunner实际运行之前调用, 且仅能调用一次// 内存 ownership:|delegate|的所有权会转移给ContentMainRunner(调用方无需再管理其生命周期)CONTENT_EXPORT void SetContentMainDelegate(ContentMainDelegate* delegate);#else // 非Android平台(Windows, Linux, macOS等)// 说明:ContentMain需由嵌入者(如Chrome)的main()函数调用, 完成每个进程的初始化设置// 定制能力:嵌入者可通过ContentMainDelegate接口自定义启动流程// 可选委托:若嵌入者无需覆盖默认启动逻辑, 可传入nullptr作为|delegate|参数// 返回值:返回进程退出码(标识启动结果或运行状态)CONTENT_EXPORT int ContentMain(ContentMainParams params);#endif#if BUILDFLAG(IS_ANDROID) // Android平台专用声明// 说明:Android平台中, Content模块的启动入口是ContentMain.java(Java层)// 该函数提供了一种方式, 为ContentMainRunner设置ContentMainDelegate委托对象// 调用限制:必须在ContentMainRunner实际运行之前调用, 且仅能调用一次// 内存 ownership:|delegate|的所有权会转移给ContentMainRunner(调用方无需再管理其生命周期)CONTENT_EXPORT void SetContentMainDelegate(ContentMainDelegate* delegate);#else // 非Android平台(Windows, Linux, macOS等)// 说明:ContentMain需由嵌入者(如Chrome)的main()函数调用, 完成每个进程的初始化设置// 定制能力:嵌入者可通过ContentMainDelegate接口自定义启动流程// 可选委托:若嵌入者无需覆盖默认启动逻辑, 可传入nullptr作为|delegate|参数// 返回值:返回进程退出码(标识启动结果或运行状态)CONTENT_EXPORT int ContentMain(ContentMainParams params);#endifNO_STACK_PROTECTOR int ContentMain(ContentMainParams params) { // 创建ContentMainRunner实例(Content模块的核心运行器, 负责进程启动和生命周期管理) auto runner = ContentMainRunner::Create(); // 执行内容进程启动逻辑:传入参数和runner实例, 返回进程退出码 return RunContentProcess(std::move(params), runner.get());}NO_STACK_PROTECTOR int RunContentProcess( ContentMainParams params, ContentMainRunner* content_main_runner) { // 未初始化FeatureList时访问特性直接失败(避免默认行为导致的隐藏问题) base::FeatureList::FailOnFeatureAccessWithoutFeatureList(); int exit_code = -1; // 进程退出码, 默认初始化为-1(表示未正常启动)#if BUILDFLAG(IS_MAC) // macOS平台:创建自动释放池(管理Objective-C对象生命周期) base::apple::ScopedNSAutoreleasePool autorelease_pool;#endif // 标记是否已初始化的静态变量:Android平台可能不重启进程而重新运行Main(), 需避免重复初始化 static bool is_initialized = false;#if !BUILDFLAG(IS_ANDROID) // 非Android平台强制检查:确保仅初始化一次(DCHECK断言失败会崩溃) DCHECK(!is_initialized);#endif // 已初始化:重新初始化参数(适用于Android平台进程复用场景) if (is_initialized) { content_main_runner->ReInitializeParams(std::move(params)); } // 未初始化:执行首次初始化流程 else { is_initialized = true; // 标记为已初始化#if BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(USE_ALLOCATOR_SHIM) // Apple平台且启用分配器垫片:初始化垫片 allocator_shim::InitializeAllocatorShim();#endif // 启用内存不足时的终止机制(确保OOM错误正确通知系统) base::EnableTerminationOnOutOfMemory(); // 注册Abseil库的崩溃钩子(统一崩溃处理流程) logging::RegisterAbslAbortHook();#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Linux/ChromeOS平台:禁用DBUS自动启动 // 未设置DBUS_SESSION_BUS_ADDRESS时, 强制设为"disabled:", 避免自动启动导致的hang问题 // 如需恢复自动启动, 可在启动前设置环境变量为"autolaunch:" const int kNoOverrideIfAlreadySet = 0; setenv("DBUS_SESSION_BUS_ADDRESS", "disabled:", kNoOverrideIfAlreadySet);#endif#if BUILDFLAG(IS_WIN) // Windows平台专用初始化 // 注册无效参数处理函数(捕获CRT库的无效参数错误) base::win::RegisterInvalidParamHandler(); // 创建ATL模块(支持UI组件的COM对象) ui::win::CreateATLModuleIfNeeded();#endif // BUILDFLAG(IS_WIN)#if !BUILDFLAG(IS_ANDROID) // 非Android平台:初始化命令行 // Android平台在库加载时已初始化命令行, 无需重复处理 int argc = 0; const char** argv = nullptr;#if !BUILDFLAG(IS_WIN) // 非Windows平台:从参数获取命令行(Windows平台忽略argc/argv) argc = params.argc; argv = params.argv;#endif // 初始化命令行单例 base::CommandLine::Init(argc, argv);#if BUILDFLAG(IS_POSIX) // POSIX平台:从文件描述符表填充文件描述符存储 PopulateFileDescriptorStoreFromFdTable();#endif // 启用堆损坏时的终止机制(检测堆篡改并崩溃) base::EnableTerminationOnHeapCorruption(); // 根据命令行设置进程标题 base::SetProcessTitleFromCommandLine(argv);#endif // !BUILDFLAG(IS_ANDROID) // 初始化Unix时间戳基准(确保TimeTicks与Unix时间戳对齐) InitTimeTicksAtUnixEpoch();// POSIX平台(排除Android):设置区域和信号处理#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) // 设置C库区域为系统默认:确保命令行解析和文件名编码正确 setlocale(LC_ALL, ""); // 强制数字区域为"C" locale:避免区域敏感的数字格式转换(UI数字转换通过ICU处理) setlocale(LC_NUMERIC, "C"); // 设置信号处理器(如捕获崩溃信号生成栈跟踪) SetupSignalHandlers();#endif#if BUILDFLAG(IS_WIN) // Windows平台:初始化CRT(C运行时库) base::win::SetupCRT(*base::CommandLine::ForCurrentProcess());#endif#if BUILDFLAG(IS_MAC) // macOS平台专用初始化 // 将自动释放池赋值给参数(供后续主循环刷新) params.autorelease_pool = &autorelease_pool; // 初始化macOS平台相关配置(如安全设置, 资源路径) InitializeMac();#endif#if BUILDFLAG(IS_IOS) // iOS平台专用配置 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); // 启用视口支持和移动User-Agent command_line->AppendSwitch(switches::kEnableViewport); command_line->AppendSwitch(embedder_support::kUseMobileUserAgent);#if BUILDFLAG(IS_IOS_TVOS) // tvOS平台:默认启用单进程模式和空间导航 command_line->AppendSwitch(switches::kSingleProcess); command_line->AppendSwitch(switches::kEnableSpatialNavigation);#endif#endif#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && !defined(COMPONENT_BUILD) // ChromeOS/Linux非组件构建:启用文件描述符所有权强制检查(安全机制) base::subtle::EnableFDOwnershipEnforcement(true);#endif // 注册UI路径提供器(供资源加载时解析路径) ui::RegisterPathProvider(); // 初始化ContentMainRunner(传入参数, 返回退出码) exit_code = content_main_runner->Initialize(std::move(params)); // 初始化失败(退出码>=0):直接返回结果(不执行后续运行逻辑) if (exit_code >= 0) { return exit_code; }#if BUILDFLAG(IS_WIN) // Windows平台:路由标准输入输出到控制台 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kHeadless)) { // 无头模式:路由stdio到控制台(不自动创建控制台) base::RouteStdioToConsole(/*create_console_if_not_found*/ false); } else if (command_line->HasSwitch(switches::kEnableLogging)) { // 启用日志:根据参数决定是否创建控制台(避免子进程重复创建) bool create_console = command_line->GetSwitchValueASCII( switches::kEnableLogging) != "handle"; base::RouteStdioToConsole(create_console); }#endif // 添加跟踪启用状态观察者 base::trace_event::TraceLog::GetInstance()->AddOwnedEnabledStateObserver( base::WrapUnique(new TracingEnabledStateObserver)); } // 子进程:执行通用子进程初始化 if (IsSubprocess()) CommonSubprocessInit(); // 运行ContentMainRunner(启动核心逻辑, 如主循环, 进程任务) exit_code = content_main_runner->Run();#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) // 非Android/iOS平台:执行关闭清理 content_main_runner->Shutdown();#endif return exit_code; // 返回进程退出码}NO_STACK_PROTECTOR int ContentMain(ContentMainParams params) { // 创建ContentMainRunner实例(Content模块的核心运行器, 负责进程启动和生命周期管理) auto runner = ContentMainRunner::Create(); // 执行内容进程启动逻辑:传入参数和runner实例, 返回进程退出码 return RunContentProcess(std::move(params), runner.get());}NO_STACK_PROTECTOR int RunContentProcess( ContentMainParams params, ContentMainRunner* content_main_runner) { // 未初始化FeatureList时访问特性直接失败(避免默认行为导致的隐藏问题) base::FeatureList::FailOnFeatureAccessWithoutFeatureList(); int exit_code = -1; // 进程退出码, 默认初始化为-1(表示未正常启动)#if BUILDFLAG(IS_MAC) // macOS平台:创建自动释放池(管理Objective-C对象生命周期) base::apple::ScopedNSAutoreleasePool autorelease_pool;#endif // 标记是否已初始化的静态变量:Android平台可能不重启进程而重新运行Main(), 需避免重复初始化 static bool is_initialized = false;#if !BUILDFLAG(IS_ANDROID) // 非Android平台强制检查:确保仅初始化一次(DCHECK断言失败会崩溃) DCHECK(!is_initialized);#endif // 已初始化:重新初始化参数(适用于Android平台进程复用场景) if (is_initialized) { content_main_runner->ReInitializeParams(std::move(params)); } // 未初始化:执行首次初始化流程 else { is_initialized = true; // 标记为已初始化#if BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(USE_ALLOCATOR_SHIM) // Apple平台且启用分配器垫片:初始化垫片 allocator_shim::InitializeAllocatorShim();#endif // 启用内存不足时的终止机制(确保OOM错误正确通知系统) base::EnableTerminationOnOutOfMemory(); // 注册Abseil库的崩溃钩子(统一崩溃处理流程) logging::RegisterAbslAbortHook();#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Linux/ChromeOS平台:禁用DBUS自动启动 // 未设置DBUS_SESSION_BUS_ADDRESS时, 强制设为"disabled:", 避免自动启动导致的hang问题 // 如需恢复自动启动, 可在启动前设置环境变量为"autolaunch:" const int kNoOverrideIfAlreadySet = 0; setenv("DBUS_SESSION_BUS_ADDRESS", "disabled:", kNoOverrideIfAlreadySet);#endif#if BUILDFLAG(IS_WIN) // Windows平台专用初始化 // 注册无效参数处理函数(捕获CRT库的无效参数错误) base::win::RegisterInvalidParamHandler(); // 创建ATL模块(支持UI组件的COM对象) ui::win::CreateATLModuleIfNeeded();#endif // BUILDFLAG(IS_WIN)#if !BUILDFLAG(IS_ANDROID) // 非Android平台:初始化命令行 // Android平台在库加载时已初始化命令行, 无需重复处理 int argc = 0; const char** argv = nullptr;#if !BUILDFLAG(IS_WIN) // 非Windows平台:从参数获取命令行(Windows平台忽略argc/argv) argc = params.argc; argv = params.argv;#endif // 初始化命令行单例 base::CommandLine::Init(argc, argv);#if BUILDFLAG(IS_POSIX) // POSIX平台:从文件描述符表填充文件描述符存储 PopulateFileDescriptorStoreFromFdTable();#endif // 启用堆损坏时的终止机制(检测堆篡改并崩溃) base::EnableTerminationOnHeapCorruption(); // 根据命令行设置进程标题 base::SetProcessTitleFromCommandLine(argv);#endif // !BUILDFLAG(IS_ANDROID) // 初始化Unix时间戳基准(确保TimeTicks与Unix时间戳对齐) InitTimeTicksAtUnixEpoch();// POSIX平台(排除Android):设置区域和信号处理#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) // 设置C库区域为系统默认:确保命令行解析和文件名编码正确 setlocale(LC_ALL, ""); // 强制数字区域为"C" locale:避免区域敏感的数字格式转换(UI数字转换通过ICU处理) setlocale(LC_NUMERIC, "C"); // 设置信号处理器(如捕获崩溃信号生成栈跟踪) SetupSignalHandlers();#endif#if BUILDFLAG(IS_WIN) // Windows平台:初始化CRT(C运行时库) base::win::SetupCRT(*base::CommandLine::ForCurrentProcess());#endif#if BUILDFLAG(IS_MAC) // macOS平台专用初始化 // 将自动释放池赋值给参数(供后续主循环刷新) params.autorelease_pool = &autorelease_pool; // 初始化macOS平台相关配置(如安全设置, 资源路径) InitializeMac();#endif#if BUILDFLAG(IS_IOS) // iOS平台专用配置 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); // 启用视口支持和移动User-Agent command_line->AppendSwitch(switches::kEnableViewport); command_line->AppendSwitch(embedder_support::kUseMobileUserAgent);#if BUILDFLAG(IS_IOS_TVOS) // tvOS平台:默认启用单进程模式和空间导航 command_line->AppendSwitch(switches::kSingleProcess); command_line->AppendSwitch(switches::kEnableSpatialNavigation);#endif#endif#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && !defined(COMPONENT_BUILD) // ChromeOS/Linux非组件构建:启用文件描述符所有权强制检查(安全机制) base::subtle::EnableFDOwnershipEnforcement(true);#endif // 注册UI路径提供器(供资源加载时解析路径) ui::RegisterPathProvider(); // 初始化ContentMainRunner(传入参数, 返回退出码) exit_code = content_main_runner->Initialize(std::move(params)); // 初始化失败(退出码>=0):直接返回结果(不执行后续运行逻辑) if (exit_code >= 0) { return exit_code; }#if BUILDFLAG(IS_WIN) // Windows平台:路由标准输入输出到控制台 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kHeadless)) { // 无头模式:路由stdio到控制台(不自动创建控制台) base::RouteStdioToConsole(/*create_console_if_not_found*/ false); } else if (command_line->HasSwitch(switches::kEnableLogging)) { // 启用日志:根据参数决定是否创建控制台(避免子进程重复创建) bool create_console = command_line->GetSwitchValueASCII( switches::kEnableLogging) != "handle"; base::RouteStdioToConsole(create_console); }#endif // 添加跟踪启用状态观察者 base::trace_event::TraceLog::GetInstance()->AddOwnedEnabledStateObserver( base::WrapUnique(new TracingEnabledStateObserver)); } // 子进程:执行通用子进程初始化 if (IsSubprocess()) CommonSubprocessInit(); // 运行ContentMainRunner(启动核心逻辑, 如主循环, 进程任务) exit_code = content_main_runner->Run();#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) // 非Android/iOS平台:执行关闭清理 content_main_runner->Shutdown();#endif return exit_code; // 返回进程退出码}NO_STACK_PROTECTOR int ContentMainRunnerImpl::Run() { // 断言校验:确保已初始化, 参数有效, 未执行关闭操作(DCHECK失败会崩溃, 仅调试模式生效) DCHECK(is_initialized_); DCHECK(content_main_params_); DCHECK(!is_shutdown_); // 获取当前进程的命令行对象, 解析进程类型(如浏览器进程, 渲染进程, GPU进程等) const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType); // 空字符串表示浏览器主进程#if defined(ADDRESS_SANITIZER) // 启用地址 sanitizer(内存检测工具)时 // 初始化ASAN服务, 注册错误回调函数(用于上报进程信息, 辅助内存错误调试) base::debug::AsanService::GetInstance()->Initialize(); base::debug::AsanService::GetInstance()->AddErrorCallback(AsanProcessInfoCB);#endif // 子进程(非浏览器主进程)专属初始化逻辑 bool needs_startup_tracing_after_sandbox_init = false; // 标记是否需在沙箱初始化后启动跟踪 if (!process_type.empty()) { // 排除Zygote进程(进程孵化器, 无需以下初始化) if (process_type != switches::kZygoteProcess) { // 委托对象决定是否创建特性列表:初始化实验特性和字段试用配置 if (delegate_->ShouldCreateFeatureList( ContentMainDelegate::InvokedInChildProcess())) { InitializeFieldTrialAndFeatureList(); }#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Linux/ChromeOS平台:初始化跟踪系统 if (process_type == switches::kGpuProcess) { // GPU进程:初始化跟踪(禁用消费者, 支持线程重启跟踪) tracing::InitTracingPostFeatureList(/*enable_consumer=*/false, /*will_trace_thread_restart=*/true); } else { // 其他子进程:标记需在沙箱初始化后启动跟踪 needs_startup_tracing_after_sandbox_init = true; }#else // 非Linux/ChromeOS平台:初始化跟踪(禁用消费者, 不支持线程重启跟踪) tracing::InitTracingPostFeatureList(/*enable_consumer=*/false, /*will_trace_thread_restart=*/false);#endif // 委托对象决定是否初始化Mojo核心(进程间通信框架) if (delegate_->ShouldInitializeMojo( ContentMainDelegate::InvokedInChildProcess())) { InitializeMojoCore(); } // 委托对象执行早期初始化后回调(子进程专属后续配置) delegate_->PostEarlyInitialization( ContentMainDelegate::InvokedInChildProcess()); // 根据进程类型重新配置分区分配器(内存分配优化) base::allocator::PartitionAllocSupport::Get() ->ReconfigureAfterFeatureListInit(process_type); } } // 构造主函数参数对象(传递给具体进程类型的启动逻辑) MainFunctionParams main_params(command_line); // 传递UI任务, 创建主组件的回调函数, 沙箱后跟踪标记 main_params.ui_task = std::move(content_main_params_->ui_task); main_params.created_main_parts_closure = std::move(content_main_params_->created_main_parts_closure); main_params.needs_startup_tracing_after_sandbox_init = needs_startup_tracing_after_sandbox_init;#if BUILDFLAG(IS_WIN) // Windows平台:传递沙箱信息 main_params.sandbox_info = content_main_params_->sandbox_info;#elif BUILDFLAG(IS_MAC) // macOS平台:传递自动释放池 main_params.autorelease_pool = content_main_params_->autorelease_pool;#endif // 标记是否启用最小浏览器模式(仅加载核心组件, 用于轻量场景) const bool start_minimal_browser = content_main_params_->minimal_browser_mode; // 释放ContentMainParams资源(后续不再复用) // 注:因MainFunctionParams位于common目录, 无法直接依赖ContentMainParams, 故通过逐个字段传递 content_main_params_.reset(); // 注册主线程工厂(用于创建主线程相关组件, 如消息循环) RegisterMainThreadFactories(); // 进程类型为空(浏览器主进程):执行浏览器进程启动逻辑 if (process_type.empty()) return RunBrowser(std::move(main_params), start_minimal_browser); // 子进程:执行对应类型进程的启动逻辑(如渲染进程, GPU进程等) return RunOtherNamedProcessTypeMain(process_type, std::move(main_params), delegate_);}NO_STACK_PROTECTOR int ContentMainRunnerImpl::Run() { // 断言校验:确保已初始化, 参数有效, 未执行关闭操作(DCHECK失败会崩溃, 仅调试模式生效) DCHECK(is_initialized_); DCHECK(content_main_params_); DCHECK(!is_shutdown_); // 获取当前进程的命令行对象, 解析进程类型(如浏览器进程, 渲染进程, GPU进程等) const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType); // 空字符串表示浏览器主进程#if defined(ADDRESS_SANITIZER) // 启用地址 sanitizer(内存检测工具)时 // 初始化ASAN服务, 注册错误回调函数(用于上报进程信息, 辅助内存错误调试) base::debug::AsanService::GetInstance()->Initialize(); base::debug::AsanService::GetInstance()->AddErrorCallback(AsanProcessInfoCB);#endif // 子进程(非浏览器主进程)专属初始化逻辑 bool needs_startup_tracing_after_sandbox_init = false; // 标记是否需在沙箱初始化后启动跟踪 if (!process_type.empty()) { // 排除Zygote进程(进程孵化器, 无需以下初始化) if (process_type != switches::kZygoteProcess) { // 委托对象决定是否创建特性列表:初始化实验特性和字段试用配置 if (delegate_->ShouldCreateFeatureList( ContentMainDelegate::InvokedInChildProcess())) { InitializeFieldTrialAndFeatureList(); }#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Linux/ChromeOS平台:初始化跟踪系统 if (process_type == switches::kGpuProcess) { // GPU进程:初始化跟踪(禁用消费者, 支持线程重启跟踪) tracing::InitTracingPostFeatureList(/*enable_consumer=*/false, /*will_trace_thread_restart=*/true); } else { // 其他子进程:标记需在沙箱初始化后启动跟踪 needs_startup_tracing_after_sandbox_init = true; }#else // 非Linux/ChromeOS平台:初始化跟踪(禁用消费者, 不支持线程重启跟踪) tracing::InitTracingPostFeatureList(/*enable_consumer=*/false, /*will_trace_thread_restart=*/false);#endif // 委托对象决定是否初始化Mojo核心(进程间通信框架) if (delegate_->ShouldInitializeMojo( ContentMainDelegate::InvokedInChildProcess())) { InitializeMojoCore(); } // 委托对象执行早期初始化后回调(子进程专属后续配置) delegate_->PostEarlyInitialization( ContentMainDelegate::InvokedInChildProcess()); // 根据进程类型重新配置分区分配器(内存分配优化) base::allocator::PartitionAllocSupport::Get() ->ReconfigureAfterFeatureListInit(process_type); } } // 构造主函数参数对象(传递给具体进程类型的启动逻辑) MainFunctionParams main_params(command_line); // 传递UI任务, 创建主组件的回调函数, 沙箱后跟踪标记 main_params.ui_task = std::move(content_main_params_->ui_task); main_params.created_main_parts_closure = std::move(content_main_params_->created_main_parts_closure); main_params.needs_startup_tracing_after_sandbox_init = needs_startup_tracing_after_sandbox_init;#if BUILDFLAG(IS_WIN) // Windows平台:传递沙箱信息 main_params.sandbox_info = content_main_params_->sandbox_info;#elif BUILDFLAG(IS_MAC) // macOS平台:传递自动释放池 main_params.autorelease_pool = content_main_params_->autorelease_pool;#endif // 标记是否启用最小浏览器模式(仅加载核心组件, 用于轻量场景) const bool start_minimal_browser = content_main_params_->minimal_browser_mode; // 释放ContentMainParams资源(后续不再复用) // 注:因MainFunctionParams位于common目录, 无法直接依赖ContentMainParams, 故通过逐个字段传递 content_main_params_.reset(); // 注册主线程工厂(用于创建主线程相关组件, 如消息循环) RegisterMainThreadFactories(); // 进程类型为空(浏览器主进程):执行浏览器进程启动逻辑 if (process_type.empty()) return RunBrowser(std::move(main_params), start_minimal_browser); // 子进程:执行对应类型进程的启动逻辑(如渲染进程, GPU进程等) return RunOtherNamedProcessTypeMain(process_type, std::move(main_params), delegate_);}static void RegisterMainThreadFactories() { UtilityProcessHost::RegisterUtilityMainThreadFactory( CreateInProcessUtilityThread); RenderProcessHostImpl::RegisterRendererMainThreadFactory( CreateInProcessRendererThread); content::RegisterGpuMainThreadFactory(CreateInProcessGpuThread);}// utilityUtilityMainThreadFactoryFunction g_utility_main_thread_factory = nullptr;void UtilityProcessHost::RegisterUtilityMainThreadFactory( UtilityMainThreadFactoryFunction create) { g_utility_main_thread_factory = create;}base::Thread* CreateInProcessUtilityThread( const InProcessChildThreadParams& params) { return new InProcessUtilityThread(params);}// rendererRendererMainThreadFactoryFunction g_renderer_main_thread_factory = nullptr;void RenderProcessHostImpl::RegisterRendererMainThreadFactory( RendererMainThreadFactoryFunction create) { g_renderer_main_thread_factory = create;}base::Thread* CreateInProcessRendererThread( const InProcessChildThreadParams& params, int32_t renderer_client_id) { return new InProcessRendererThread(params, renderer_client_id);}// gpuGpuMainThreadFactoryFunction g_gpu_main_thread_factory = nullptr;void RegisterGpuMainThreadFactory(GpuMainThreadFactoryFunction create) { g_gpu_main_thread_factory = create;}base::Thread* CreateInProcessGpuThread( const InProcessChildThreadParams& params, const gpu::GpuPreferences& gpu_preferences) { return new InProcessGpuThread(params, gpu_preferences);}static void RegisterMainThreadFactories() { UtilityProcessHost::RegisterUtilityMainThreadFactory( CreateInProcessUtilityThread); RenderProcessHostImpl::RegisterRendererMainThreadFactory( CreateInProcessRendererThread); content::RegisterGpuMainThreadFactory(CreateInProcessGpuThread);}// utilityUtilityMainThreadFactoryFunction g_utility_main_thread_factory = nullptr;void UtilityProcessHost::RegisterUtilityMainThreadFactory( UtilityMainThreadFactoryFunction create) { g_utility_main_thread_factory = create;}base::Thread* CreateInProcessUtilityThread( const InProcessChildThreadParams& params) { return new InProcessUtilityThread(params);}// rendererRendererMainThreadFactoryFunction g_renderer_main_thread_factory = nullptr;void RenderProcessHostImpl::RegisterRendererMainThreadFactory( RendererMainThreadFactoryFunction create) { g_renderer_main_thread_factory = create;}base::Thread* CreateInProcessRendererThread( const InProcessChildThreadParams& params, int32_t renderer_client_id) { return new InProcessRendererThread(params, renderer_client_id);}// gpuGpuMainThreadFactoryFunction g_gpu_main_thread_factory = nullptr;void RegisterGpuMainThreadFactory(GpuMainThreadFactoryFunction create) { g_gpu_main_thread_factory = create;}base::Thread* CreateInProcessGpuThread( const InProcessChildThreadParams& params, const gpu::GpuPreferences& gpu_preferences) { return new InProcessGpuThread(params, gpu_preferences);}int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params, bool start_minimal_browser) { TRACE_EVENT_INSTANT0("startup", "ContentMainRunnerImpl::RunBrowser(begin)", TRACE_EVENT_SCOPE_THREAD); // 检查浏览器主循环是否已启动, 避免重复执行 if (is_browser_main_loop_started_) return -1; // 非单进程模式下(默认多进程):禁用Mojo同步调用中断 // 多进程场景下需要稳定的IPC通信, 防止同步调用被中断 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSingleProcess)) { mojo::SyncCallRestrictions::DisableSyncCallInterrupts(); } // 可能解压Variations状态文件(Variations是Chrome的A/B测试框架) // 加载测试配置, 功能开关等信息 variations::MaybeUnpackVariationsStateFile(); // 如果Mojo IPC支持未初始化(首次进入), 执行初始化流程 if (!mojo_ipc_support_) { // 标记当前是否在浏览器进程中执行(区分测试/正式环境) const ContentMainDelegate::InvokedInBrowserProcess invoked_in_browser{ .is_running_test = !main_params.ui_task.is_null()}; // 委托类判断是否需要创建功能列表(FeatureList管理所有功能开关) if (delegate_->ShouldCreateFeatureList(invoked_in_browser)) { // 初始化字段试验列表和功能列表, 故意泄漏对象(进程生命周期内持续使用) // 无需在进程退出时清理, 无性能损失 base::FieldTrialList* leaked_field_trial_list = SetUpFieldTrialsAndFeatureList().release(); // 标记对象为泄漏(避免内存检测工具误报) ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list); // 忽略未使用变量警告(实际已通过泄漏方式使用) std::ignore = leaked_field_trial_list; } // 委托类判断是否需要初始化Mojo(IPC通信核心) if (delegate_->ShouldInitializeMojo(invoked_in_browser)) { InitializeMojoCore(); // 初始化Mojo核心服务 } // 创建浏览器内存消费者注册表(用于内存使用监控和分析) browser_memory_consumer_registry_ = std::make_unique< base::ScopedMemoryConsumerRegistry<BrowserMemoryConsumerRegistry>>(); // 执行浏览器主流程前的预处理(委托给子类实现, 如初始化第三方组件) std::optional<int> pre_browser_main_exit_code = delegate_->PreBrowserMain(); // 如果预处理返回退出码, 直接终止流程(如预处理失败) if (pre_browser_main_exit_code.has_value()) return pre_browser_main_exit_code.value();#if BUILDFLAG(IS_WIN) // Windows平台特有处理 // 如果未设置区域覆盖(locale), 使用用户首选的UI语言覆盖区域设置 // 测试环境会手动设置locale, 避免此处覆盖(保证测试一致性) if (l10n_util::GetLocaleOverrides().empty()) { l10n_util::OverrideLocaleWithUILanguageList(); }#endif // 注册浏览器线程的任务执行器(TaskExecutor) // 注意:在此之前不能向BrowserThreads投递任务(线程未初始化) // 作用:初始化主线程的UI消息循环(后续在BrowserMainLoop中标记为BrowserThread::UI) BrowserTaskExecutor::Create(); // 创建Variations ID提供器(用于A/B测试标识分配) auto* provider = delegate_->CreateVariationsIdsProvider(); if (!provider) { // 委托未创建时, 使用默认实现(基于登录状态分配ID) variations::VariationsIdsProvider::CreateInstance( variations::VariationsIdsProvider::Mode::kUseSignedInState); } // 早期初始化后的后续处理(委托给子类, 如初始化扩展服务) std::optional<int> post_early_initialization_exit_code = delegate_->PostEarlyInitialization(invoked_in_browser); // 若返回退出码, 终止流程 if (post_early_initialization_exit_code.has_value()) return post_early_initialization_exit_code.value(); // 启动挂起监控器(HangWatcher):需在功能列表可用, IO线程启动前初始化 // 用于检测主线程/IO线程挂起, 收集堆栈信息辅助调试 if (base::HangWatcher::IsEnabled()) { base::HangWatcher::CreateHangWatcherInstance(); // 创建挂起监控实例 // 注册主线程到挂起监控器, 且不取消注册(监控器为泄漏对象, 进程生命周期有效) base::ScopedClosureRunner unregister_thread_closure( base::HangWatcher::RegisterThread( base::HangWatcher::ThreadType::kMainThread)); // 释放闭包所有权(避免自动取消注册) std::ignore = unregister_thread_closure.Release(); base::HangWatcher::GetInstance()->Start(); // 启动挂起监控 }#if BUILDFLAG(IS_ANDROID) // Android平台特有:初始化性能追踪(Perfetto) // WebView可能已初始化Perfetto, 由委托判断是否需要在此处初始化 if (delegate_->ShouldInitializePerfetto(invoked_in_browser)) { tracing::InitTracingPostFeatureList( /*enable_consumer=*/true, // 启用追踪消费者(接收追踪数据) /*will_trace_thread_restart=*/false, // 不追踪线程重启 base::BindRepeating(&ShouldAllowSystemTracingConsumer)); // 系统追踪消费者权限判断 }#else // 非Android平台:直接初始化Perfetto追踪 tracing::InitTracingPostFeatureList( /*enable_consumer=*/true, /*will_trace_thread_restart=*/false, base::BindRepeating(&ShouldAllowSystemTracingConsumer));#endif // 启动浏览器线程池(ThreadPool):需在FeatureList创建后执行 // 线程池用于处理后台任务(如下载, 缓存清理等) StartBrowserThreadPool(); // 安装PartitionAlloc内存分配器的调度循环隔离任务观察者 // 作用:监控内存分配/释放, 处理隔离区(quarantine)逻辑, 提升内存安全性 BrowserTaskExecutor:: InstallPartitionAllocSchedulerLoopQuarantineTaskObserver(); // 初始化电源监控器(PowerMonitor):精简模式下也需要 // BrowserMainLoop会判断是否已初始化, 避免重复执行 // 参数1:电源监控设备源(获取设备电源状态) // 参数2:是否发送全局事件(通知其他模块电源状态变化) base::PowerMonitor::GetInstance()->Initialize( MakePowerMonitorDeviceSource(), /*emit_global_event=*/true); // 确保进程可见性追踪器在主线程创建(单例模式) // 用于监控浏览器进程是否处于前台/后台状态 ProcessVisibilityTracker::GetInstance();#if BUILDFLAG(IS_ANDROID) // Android平台特有:初始化性能/电池指标 SetupCpuTimeMetrics(); // 配置CPU时间指标收集 // 创建Android电池指标实例(依赖PowerMonitor已初始化) AndroidBatteryMetrics::CreateInstance();#endif // 通知浏览器客户端:设置是否为最小化模式 GetContentClient()->browser()->SetIsMinimalMode(start_minimal_browser); if (start_minimal_browser) { ForceInProcessNetworkService(); // 强制启用进程内网络服务(最小化模式简化架构) // 最小化模式不通过常规方式初始化First-Party Sets(第一方集合) // 手动初始化:使用空路径和本地集合声明 content::FirstPartySetsHandlerImpl::GetInstance()->Init( base::FilePath(), net::LocalSetDeclaration()); } // 创建可释放共享内存管理器 // 用于管理可回收的共享内存(如渲染进程间共享的缓存数据) discardable_shared_memory_manager_ = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>(); // 初始化Mojo IPC支持:创建IO线程并绑定 // Mojo IPC的核心线程, 负责跨进程通信的IO操作 mojo_ipc_support_ = std::make_unique<MojoIpcSupport>(BrowserTaskExecutor::CreateIOThread()); // 绑定浏览器控制接口:处理Mojo邀请(跨进程通信初始化) GetContentClient()->browser()->BindBrowserControlInterface( MaybeAcceptMojoInvitation()); // 为下载模块设置IO线程任务执行器 // 下载任务需在IO线程执行(网络请求, 文件写入等) download::SetIOTaskRunner(mojo_ipc_support_->io_thread()->task_runner()); // 初始化浏览器内存监控客户端 // 用于收集和上报浏览器进程内存使用数据 InitializeBrowserMemoryInstrumentationClient();#if BUILDFLAG(IS_ANDROID) // Android平台特有:最小化模式启动完成通知 if (start_minimal_browser) { // 向主线程任务队列投递"最小化浏览器启动完成"任务 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(&MinimalBrowserStartupComplete)); }#endif } // 未指定进程类型时, 默认为浏览器进程 // 初始化PartitionAlloc内存分配器(FeatureList初始化后) base::allocator::PartitionAllocSupport::Get() ->ReconfigureAfterFeatureListInit(""); // 初始化PartitionAlloc内存分配器(任务执行器初始化后) base::allocator::PartitionAllocSupport::Get()->ReconfigureAfterTaskRunnerInit( ""); // 最小化模式下:打印日志并返回(无需启动完整浏览器流程) if (start_minimal_browser) { DVLOG(0) << "Chrome is running in minimal browser mode."; // 日志级别0(强制输出) return -1; } // 标记浏览器主循环已启动(防止重复执行) is_browser_main_loop_started_ = true; // 创建浏览器启动数据并传入主参数(包含Mojo IPC配置等) main_params.startup_data = mojo_ipc_support_->CreateBrowserStartupData(); // 执行浏览器进程主逻辑, 返回退出码 return RunBrowserProcessMain(std::move(main_params), delegate_);}int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params, bool start_minimal_browser) { TRACE_EVENT_INSTANT0("startup", "ContentMainRunnerImpl::RunBrowser(begin)", TRACE_EVENT_SCOPE_THREAD); // 检查浏览器主循环是否已启动, 避免重复执行 if (is_browser_main_loop_started_) return -1; // 非单进程模式下(默认多进程):禁用Mojo同步调用中断 // 多进程场景下需要稳定的IPC通信, 防止同步调用被中断 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSingleProcess)) { mojo::SyncCallRestrictions::DisableSyncCallInterrupts(); } // 可能解压Variations状态文件(Variations是Chrome的A/B测试框架) // 加载测试配置, 功能开关等信息 variations::MaybeUnpackVariationsStateFile(); // 如果Mojo IPC支持未初始化(首次进入), 执行初始化流程 if (!mojo_ipc_support_) { // 标记当前是否在浏览器进程中执行(区分测试/正式环境) const ContentMainDelegate::InvokedInBrowserProcess invoked_in_browser{ .is_running_test = !main_params.ui_task.is_null()}; // 委托类判断是否需要创建功能列表(FeatureList管理所有功能开关) if (delegate_->ShouldCreateFeatureList(invoked_in_browser)) { // 初始化字段试验列表和功能列表, 故意泄漏对象(进程生命周期内持续使用) // 无需在进程退出时清理, 无性能损失 base::FieldTrialList* leaked_field_trial_list = SetUpFieldTrialsAndFeatureList().release(); // 标记对象为泄漏(避免内存检测工具误报) ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list); // 忽略未使用变量警告(实际已通过泄漏方式使用) std::ignore = leaked_field_trial_list; } // 委托类判断是否需要初始化Mojo(IPC通信核心) if (delegate_->ShouldInitializeMojo(invoked_in_browser)) { InitializeMojoCore(); // 初始化Mojo核心服务 } // 创建浏览器内存消费者注册表(用于内存使用监控和分析) browser_memory_consumer_registry_ = std::make_unique< base::ScopedMemoryConsumerRegistry<BrowserMemoryConsumerRegistry>>(); // 执行浏览器主流程前的预处理(委托给子类实现, 如初始化第三方组件) std::optional<int> pre_browser_main_exit_code = delegate_->PreBrowserMain(); // 如果预处理返回退出码, 直接终止流程(如预处理失败) if (pre_browser_main_exit_code.has_value()) return pre_browser_main_exit_code.value();#if BUILDFLAG(IS_WIN) // Windows平台特有处理 // 如果未设置区域覆盖(locale), 使用用户首选的UI语言覆盖区域设置 // 测试环境会手动设置locale, 避免此处覆盖(保证测试一致性) if (l10n_util::GetLocaleOverrides().empty()) { l10n_util::OverrideLocaleWithUILanguageList(); }#endif // 注册浏览器线程的任务执行器(TaskExecutor) // 注意:在此之前不能向BrowserThreads投递任务(线程未初始化) // 作用:初始化主线程的UI消息循环(后续在BrowserMainLoop中标记为BrowserThread::UI) BrowserTaskExecutor::Create(); // 创建Variations ID提供器(用于A/B测试标识分配) auto* provider = delegate_->CreateVariationsIdsProvider(); if (!provider) { // 委托未创建时, 使用默认实现(基于登录状态分配ID) variations::VariationsIdsProvider::CreateInstance( variations::VariationsIdsProvider::Mode::kUseSignedInState); } // 早期初始化后的后续处理(委托给子类, 如初始化扩展服务) std::optional<int> post_early_initialization_exit_code = delegate_->PostEarlyInitialization(invoked_in_browser); // 若返回退出码, 终止流程 if (post_early_initialization_exit_code.has_value()) return post_early_initialization_exit_code.value(); // 启动挂起监控器(HangWatcher):需在功能列表可用, IO线程启动前初始化 // 用于检测主线程/IO线程挂起, 收集堆栈信息辅助调试 if (base::HangWatcher::IsEnabled()) { base::HangWatcher::CreateHangWatcherInstance(); // 创建挂起监控实例 // 注册主线程到挂起监控器, 且不取消注册(监控器为泄漏对象, 进程生命周期有效) base::ScopedClosureRunner unregister_thread_closure( base::HangWatcher::RegisterThread( base::HangWatcher::ThreadType::kMainThread)); // 释放闭包所有权(避免自动取消注册) std::ignore = unregister_thread_closure.Release(); base::HangWatcher::GetInstance()->Start(); // 启动挂起监控 }#if BUILDFLAG(IS_ANDROID) // Android平台特有:初始化性能追踪(Perfetto) // WebView可能已初始化Perfetto, 由委托判断是否需要在此处初始化 if (delegate_->ShouldInitializePerfetto(invoked_in_browser)) { tracing::InitTracingPostFeatureList( /*enable_consumer=*/true, // 启用追踪消费者(接收追踪数据) /*will_trace_thread_restart=*/false, // 不追踪线程重启 base::BindRepeating(&ShouldAllowSystemTracingConsumer)); // 系统追踪消费者权限判断 }#else // 非Android平台:直接初始化Perfetto追踪 tracing::InitTracingPostFeatureList( /*enable_consumer=*/true, /*will_trace_thread_restart=*/false, base::BindRepeating(&ShouldAllowSystemTracingConsumer));#endif // 启动浏览器线程池(ThreadPool):需在FeatureList创建后执行 // 线程池用于处理后台任务(如下载, 缓存清理等) StartBrowserThreadPool(); // 安装PartitionAlloc内存分配器的调度循环隔离任务观察者 // 作用:监控内存分配/释放, 处理隔离区(quarantine)逻辑, 提升内存安全性 BrowserTaskExecutor:: InstallPartitionAllocSchedulerLoopQuarantineTaskObserver(); // 初始化电源监控器(PowerMonitor):精简模式下也需要 // BrowserMainLoop会判断是否已初始化, 避免重复执行 // 参数1:电源监控设备源(获取设备电源状态) // 参数2:是否发送全局事件(通知其他模块电源状态变化) base::PowerMonitor::GetInstance()->Initialize( MakePowerMonitorDeviceSource(), /*emit_global_event=*/true); // 确保进程可见性追踪器在主线程创建(单例模式) // 用于监控浏览器进程是否处于前台/后台状态 ProcessVisibilityTracker::GetInstance();#if BUILDFLAG(IS_ANDROID) // Android平台特有:初始化性能/电池指标 SetupCpuTimeMetrics(); // 配置CPU时间指标收集 // 创建Android电池指标实例(依赖PowerMonitor已初始化) AndroidBatteryMetrics::CreateInstance();#endif // 通知浏览器客户端:设置是否为最小化模式 GetContentClient()->browser()->SetIsMinimalMode(start_minimal_browser); if (start_minimal_browser) { ForceInProcessNetworkService(); // 强制启用进程内网络服务(最小化模式简化架构) // 最小化模式不通过常规方式初始化First-Party Sets(第一方集合) // 手动初始化:使用空路径和本地集合声明 content::FirstPartySetsHandlerImpl::GetInstance()->Init( base::FilePath(), net::LocalSetDeclaration()); } // 创建可释放共享内存管理器 // 用于管理可回收的共享内存(如渲染进程间共享的缓存数据) discardable_shared_memory_manager_ = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>(); // 初始化Mojo IPC支持:创建IO线程并绑定 // Mojo IPC的核心线程, 负责跨进程通信的IO操作 mojo_ipc_support_ = std::make_unique<MojoIpcSupport>(BrowserTaskExecutor::CreateIOThread()); // 绑定浏览器控制接口:处理Mojo邀请(跨进程通信初始化) GetContentClient()->browser()->BindBrowserControlInterface( MaybeAcceptMojoInvitation()); // 为下载模块设置IO线程任务执行器 // 下载任务需在IO线程执行(网络请求, 文件写入等) download::SetIOTaskRunner(mojo_ipc_support_->io_thread()->task_runner()); // 初始化浏览器内存监控客户端 // 用于收集和上报浏览器进程内存使用数据 InitializeBrowserMemoryInstrumentationClient();#if BUILDFLAG(IS_ANDROID) // Android平台特有:最小化模式启动完成通知 if (start_minimal_browser) { // 向主线程任务队列投递"最小化浏览器启动完成"任务 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(&MinimalBrowserStartupComplete)); }#endif } // 未指定进程类型时, 默认为浏览器进程 // 初始化PartitionAlloc内存分配器(FeatureList初始化后) base::allocator::PartitionAllocSupport::Get() ->ReconfigureAfterFeatureListInit(""); // 初始化PartitionAlloc内存分配器(任务执行器初始化后) base::allocator::PartitionAllocSupport::Get()->ReconfigureAfterTaskRunnerInit( ""); // 最小化模式下:打印日志并返回(无需启动完整浏览器流程) if (start_minimal_browser) { DVLOG(0) << "Chrome is running in minimal browser mode."; // 日志级别0(强制输出) return -1; } // 标记浏览器主循环已启动(防止重复执行) is_browser_main_loop_started_ = true; // 创建浏览器启动数据并传入主参数(包含Mojo IPC配置等) main_params.startup_data = mojo_ipc_support_->CreateBrowserStartupData(); // 执行浏览器进程主逻辑, 返回退出码 return RunBrowserProcessMain(std::move(main_params), delegate_);}int RunBrowserProcessMain(MainFunctionParams main_function_params, ContentMainDelegate* delegate) {#if BUILDFLAG(IS_WIN) // Windows平台特有:处理控制台控制事件(如Ctrl+C, 关闭控制台窗口) // 由委托判断是否需要处理控制台控制事件(浏览器进程通常需要响应此类事件以优雅退出) if (delegate->ShouldHandleConsoleControlEvents()) { // 安装控制台控制处理器, 标记当前为浏览器进程(用于区分不同进程的事件处理逻辑) InstallConsoleControlHandler(/*is_browser_process=*/true); }#endif // 委托执行进程运行逻辑:传入空字符串(表示默认进程类型, 即浏览器进程)和启动参数 // 返回值为variant类型(二选一): // 1. int类型:直接返回的进程退出码(表示进程无需继续执行核心逻辑, 直接退出) // 2. MainFunctionParams类型:经过委托处理后的启动参数(需继续执行BrowserMain核心流程) auto exit_code = delegate->RunProcess("", std::move(main_function_params)); // 检查返回值是否为int类型(即委托已决定进程退出码) if (std::holds_alternative<int>(exit_code)) { // 断言退出码非负(符合系统退出码规范:非负表示正常/指定退出, 负表示异常) DCHECK_GE(std::get<int>(exit_code), 0); // 返回委托提供的退出码, 进程终止 return std::get<int>(exit_code); } // 若返回值为MainFunctionParams类型:提取参数并执行浏览器核心主流程 return BrowserMain(std::move(std::get<MainFunctionParams>(exit_code)));}int RunBrowserProcessMain(MainFunctionParams main_function_params, ContentMainDelegate* delegate) {#if BUILDFLAG(IS_WIN) // Windows平台特有:处理控制台控制事件(如Ctrl+C, 关闭控制台窗口) // 由委托判断是否需要处理控制台控制事件(浏览器进程通常需要响应此类事件以优雅退出) if (delegate->ShouldHandleConsoleControlEvents()) { // 安装控制台控制处理器, 标记当前为浏览器进程(用于区分不同进程的事件处理逻辑) InstallConsoleControlHandler(/*is_browser_process=*/true); }#endif // 委托执行进程运行逻辑:传入空字符串(表示默认进程类型, 即浏览器进程)和启动参数 // 返回值为variant类型(二选一): // 1. int类型:直接返回的进程退出码(表示进程无需继续执行核心逻辑, 直接退出) // 2. MainFunctionParams类型:经过委托处理后的启动参数(需继续执行BrowserMain核心流程) auto exit_code = delegate->RunProcess("", std::move(main_function_params)); // 检查返回值是否为int类型(即委托已决定进程退出码) if (std::holds_alternative<int>(exit_code)) { // 断言退出码非负(符合系统退出码规范:非负表示正常/指定退出, 负表示异常) DCHECK_GE(std::get<int>(exit_code), 0); // 返回委托提供的退出码, 进程终止 return std::get<int>(exit_code); } // 若返回值为MainFunctionParams类型:提取参数并执行浏览器核心主流程 return BrowserMain(std::move(std::get<MainFunctionParams>(exit_code)));}int BrowserMain(MainFunctionParams parameters) { // 记录启动跟踪事件:标记浏览器核心主流程开始(用于性能分析, 追踪启动耗时) TRACE_EVENT_INSTANT0("startup", "BrowserMain", TRACE_EVENT_SCOPE_THREAD); // 设置当前进程类型为"浏览器进程"(标记进程角色, 供其他模块判断进程类型) base::CurrentProcess::GetInstance().SetProcessType( base::CurrentProcessType::PROCESS_BROWSER); // 创建浏览器主运行器实例(BrowserMainRunnerImpl 封装了浏览器核心运行逻辑) // 采用智能指针(std::unique_ptr)管理, 自动释放资源, 避免内存泄漏 std::unique_ptr<BrowserMainRunnerImpl> main_runner( BrowserMainRunnerImpl::Create()); // 初始化浏览器主运行器:传入启动参数, 执行初始化流程(如组件初始化, 配置加载等) int exit_code = main_runner->Initialize(std::move(parameters)); // 若初始化返回非负退出码(表示初始化失败或需要直接退出), 直接返回该退出码 if (exit_code >= 0) return exit_code; // 初始化成功(exit_code < 0), 运行浏览器主循环(进入核心业务逻辑) // 此处会阻塞直到浏览器退出(如用户关闭所有窗口, 主动退出等) exit_code = main_runner->Run(); // 记录关闭开始时间(以秒为单位), 用于问题排查(如分析进程挂起) // 可与 ReportThreadHang(), TaskAnnotator::RunTaskImpl() 等地方记录的时间对比 const int64_t shutdown_time = base::TimeTicks::Now().since_origin().InSeconds(); // 强制保留该变量在调试符号中(避免编译器优化删除, 方便调试时查看) base::debug::Alias(&shutdown_time); // 执行浏览器关闭流程:释放资源, 终止子进程, 保存配置等 main_runner->Shutdown(); // 返回浏览器运行/关闭后的最终退出码 return exit_code;}int BrowserMain(MainFunctionParams parameters) { // 记录启动跟踪事件:标记浏览器核心主流程开始(用于性能分析, 追踪启动耗时) TRACE_EVENT_INSTANT0("startup", "BrowserMain", TRACE_EVENT_SCOPE_THREAD); // 设置当前进程类型为"浏览器进程"(标记进程角色, 供其他模块判断进程类型) base::CurrentProcess::GetInstance().SetProcessType( base::CurrentProcessType::PROCESS_BROWSER); // 创建浏览器主运行器实例(BrowserMainRunnerImpl 封装了浏览器核心运行逻辑) // 采用智能指针(std::unique_ptr)管理, 自动释放资源, 避免内存泄漏 std::unique_ptr<BrowserMainRunnerImpl> main_runner( BrowserMainRunnerImpl::Create()); // 初始化浏览器主运行器:传入启动参数, 执行初始化流程(如组件初始化, 配置加载等) int exit_code = main_runner->Initialize(std::move(parameters)); // 若初始化返回非负退出码(表示初始化失败或需要直接退出), 直接返回该退出码 if (exit_code >= 0) return exit_code; // 初始化成功(exit_code < 0), 运行浏览器主循环(进入核心业务逻辑) // 此处会阻塞直到浏览器退出(如用户关闭所有窗口, 主动退出等) exit_code = main_runner->Run(); // 记录关闭开始时间(以秒为单位), 用于问题排查(如分析进程挂起) // 可与 ReportThreadHang(), TaskAnnotator::RunTaskImpl() 等地方记录的时间对比 const int64_t shutdown_time = base::TimeTicks::Now().since_origin().InSeconds(); // 强制保留该变量在调试符号中(避免编译器优化删除, 方便调试时查看) base::debug::Alias(&shutdown_time); // 执行浏览器关闭流程:释放资源, 终止子进程, 保存配置等 main_runner->Shutdown(); // 返回浏览器运行/关闭后的最终退出码 return exit_code;}int BrowserMainRunnerImpl::Initialize(MainFunctionParams parameters) { // 1. 性能指标采集:记录 BrowserMainRunnerImpl 初始化的耗时(长期计时器, 用于 UMA 统计) // UMA(User Metrics Analysis)是 Chrome 用于收集用户场景性能数据的框架, 此指标用于分析启动性能瓶颈 SCOPED_UMA_HISTOGRAM_LONG_TIMER( "Startup.BrowserMainRunnerImplInitializeLongTime"); // 2. 启动跟踪:添加 Trace 事件, 用于性能分析工具(如 chrome://tracing)标记初始化开始 TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize"); // 3. Android 平台特殊逻辑:防止重复初始化 // 说明:Android 通常通过 UI 线程的一系列任务分步初始化浏览器, 若初始化过程中收到 // 系统或其他应用的二次启动请求, 需避免重复执行初始化核心流程(防止资源冲突/内存泄漏) if (!initialization_started_) { initialization_started_ = true; // 标记为已开始初始化, 阻止二次进入 // 4. 初始化 Skia 图形库核心:Skia 是 Chrome 的底层图形渲染引擎(绘制 UI, 网页内容等) // 必须在所有图形相关操作前初始化, 提供绘图, 字体渲染等基础能力 SkGraphics::Init(); // 5. 调试模式支持:若命令行带 --wait-for-debugger, 等待调试器附加(超时 60 秒) // 第二个参数 true 表示允许在后台线程等待(不阻塞主线程初始化基础逻辑) if (parameters.command_line->HasSwitch(switches::kWaitForDebugger)) { base::debug::WaitForDebugger(60, true); } // 6. 调试模式扩展:若带 --browser-startup-dialog, 弹出调试等待对话框(显式提示用户) // 常用于开发/调试场景, 手动控制初始化流程的断点时机 if (parameters.command_line->HasSwitch(switches::kBrowserStartupDialog)) { WaitForDebugger("Browser"); }#if BUILDFLAG(IS_WIN) // 7. Windows 平台:启用高 DPI 支持(适配 4K/Retina 屏幕, 避免 UI 模糊) base::win::EnableHighDPISupport(); // 8. Windows 平台:初始化 OLE(对象链接与嵌入) // 必要性:Windows 8 Metro 模式下, TSF(文本服务框架, 处理输入法, 文本编辑) // 需与消息泵交互, 必须在消息泵启动前初始化 OLE ole_initializer_ = std::make_unique<ui::ScopedOleInitializer>();#endif // BUILDFLAG(IS_WIN) // 9. 初始化字体系统:加载系统字体配置, 为 UI 控件, 网页文本渲染提供字体支持 gfx::InitializeFonts(); // 10. 提取"主部件创建完成"回调:参数中携带的闭包, 将在 BrowserMainParts 创建后执行 // 用途:嵌入者(如 Chrome 浏览器)可通过此回调注入自定义逻辑(如初始化第三方组件) auto created_main_parts_closure = std::move(parameters.created_main_parts_closure); // 11. 创建 BrowserMainLoop 实例(浏览器主循环核心) // 传递启动参数和执行围栏(scoped_execution_fence_, 用于控制初始化流程的并发安全) // BrowserMainLoop 管理整个浏览器的生命周期(初始化, 运行, 关闭)和核心组件调度 main_loop_ = std::make_unique<BrowserMainLoop>( std::move(parameters), std::move(scoped_execution_fence_)); // 12. BrowserMainLoop 基础初始化:初始化内部状态, 参数解析等轻量操作 main_loop_->Init(); // 13. 执行主部件创建回调:若存在自定义闭包, 传入 BrowserMainParts 实例执行 // 此时 BrowserMainParts 已创建, 可通过其访问浏览器核心组件接口 if (created_main_parts_closure) { std::move(created_main_parts_closure).Run(main_loop_->parts()); } // 14. 早期初始化:执行核心组件的前置初始化(如沙箱, Mojo IPC, Zygote 进程等) // 返回值 >0 表示初始化失败, 需提前退出 const int early_init_error_code = main_loop_->EarlyInitialization(); if (early_init_error_code > 0) { // 失败时创建"早期关闭"专用消息循环(确保资源正常释放, 避免崩溃) main_loop_->CreateMessageLoopForEarlyShutdown(); return early_init_error_code; // 返回错误码, 终止初始化流程 } // 15. 初始化 UI 工具包(如 Aura, Views 等):必须在使用消息循环或显示 UI 前完成 // 工具包提供窗口管理, 控件渲染, 事件处理等基础 UI 能力, 初始化失败则退出 if (!main_loop_->InitializeToolkit()) { main_loop_->CreateMessageLoopForEarlyShutdown(); return 1; } // 16. 主消息循环创建前置操作:初始化消息循环依赖的组件(如线程本地存储, 任务调度器) main_loop_->PreCreateMainMessageLoop(); // 17. 创建主消息循环:启动主线程的消息泵(如 Windows 的 GetMessage, POSIX 的 epoll) // 主消息循环是浏览器的"心脏", 负责处理 UI 事件, 网络回调, 定时任务等 main_loop_->CreateMainMessageLoop(); // 18. 主消息循环创建后置操作:注册消息处理回调, 启动辅助线程等 main_loop_->PostCreateMainMessageLoop(); // 警告:若收到 WM_ENDSESSION(Windows 系统关机/注销事件), 栈上创建的对象不会被析构 // 注意:若需在关机时执行清理逻辑, 需将代码添加到 browser_shutdown::Shutdown 或 // BrowserProcess::EndSession 中(确保关机流程能触发) // 19. 初始化输入方法框架:支持输入法切换, 文本输入, 候选词显示等功能 // 必须在 UI 工具包初始化后执行, 依赖窗口系统的输入事件接口 ui::InitializeInputMethod(); } // 20. 创建启动任务队列:将后续初始化任务(如加载扩展, 恢复标签页, 启动网络服务) // 加入主消息循环的任务队列, 等待主循环启动后按顺序执行 main_loop_->CreateStartupTasks(); // 21. 获取初始化结果码:若结果码 >0 表示存在启动错误, 直接返回 int result_code = main_loop_->GetResultCode(); if (result_code > 0) { return result_code; } // 返回 -1 表示初始化成功, 无早期终止(符合 BrowserMain 的判断逻辑:负数值表示继续执行) return -1;}int BrowserMainRunnerImpl::Initialize(MainFunctionParams parameters) { // 1. 性能指标采集:记录 BrowserMainRunnerImpl 初始化的耗时(长期计时器, 用于 UMA 统计) // UMA(User Metrics Analysis)是 Chrome 用于收集用户场景性能数据的框架, 此指标用于分析启动性能瓶颈 SCOPED_UMA_HISTOGRAM_LONG_TIMER( "Startup.BrowserMainRunnerImplInitializeLongTime"); // 2. 启动跟踪:添加 Trace 事件, 用于性能分析工具(如 chrome://tracing)标记初始化开始 TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize"); // 3. Android 平台特殊逻辑:防止重复初始化 // 说明:Android 通常通过 UI 线程的一系列任务分步初始化浏览器, 若初始化过程中收到 // 系统或其他应用的二次启动请求, 需避免重复执行初始化核心流程(防止资源冲突/内存泄漏) if (!initialization_started_) { initialization_started_ = true; // 标记为已开始初始化, 阻止二次进入 // 4. 初始化 Skia 图形库核心:Skia 是 Chrome 的底层图形渲染引擎(绘制 UI, 网页内容等) // 必须在所有图形相关操作前初始化, 提供绘图, 字体渲染等基础能力 SkGraphics::Init(); // 5. 调试模式支持:若命令行带 --wait-for-debugger, 等待调试器附加(超时 60 秒) // 第二个参数 true 表示允许在后台线程等待(不阻塞主线程初始化基础逻辑) if (parameters.command_line->HasSwitch(switches::kWaitForDebugger)) { base::debug::WaitForDebugger(60, true); } // 6. 调试模式扩展:若带 --browser-startup-dialog, 弹出调试等待对话框(显式提示用户) // 常用于开发/调试场景, 手动控制初始化流程的断点时机 if (parameters.command_line->HasSwitch(switches::kBrowserStartupDialog)) { WaitForDebugger("Browser"); }#if BUILDFLAG(IS_WIN) // 7. Windows 平台:启用高 DPI 支持(适配 4K/Retina 屏幕, 避免 UI 模糊) base::win::EnableHighDPISupport(); // 8. Windows 平台:初始化 OLE(对象链接与嵌入) // 必要性:Windows 8 Metro 模式下, TSF(文本服务框架, 处理输入法, 文本编辑) // 需与消息泵交互, 必须在消息泵启动前初始化 OLE ole_initializer_ = std::make_unique<ui::ScopedOleInitializer>();#endif // BUILDFLAG(IS_WIN) // 9. 初始化字体系统:加载系统字体配置, 为 UI 控件, 网页文本渲染提供字体支持 gfx::InitializeFonts(); // 10. 提取"主部件创建完成"回调:参数中携带的闭包, 将在 BrowserMainParts 创建后执行 // 用途:嵌入者(如 Chrome 浏览器)可通过此回调注入自定义逻辑(如初始化第三方组件) auto created_main_parts_closure = std::move(parameters.created_main_parts_closure); // 11. 创建 BrowserMainLoop 实例(浏览器主循环核心) // 传递启动参数和执行围栏(scoped_execution_fence_, 用于控制初始化流程的并发安全) // BrowserMainLoop 管理整个浏览器的生命周期(初始化, 运行, 关闭)和核心组件调度 main_loop_ = std::make_unique<BrowserMainLoop>( std::move(parameters), std::move(scoped_execution_fence_)); // 12. BrowserMainLoop 基础初始化:初始化内部状态, 参数解析等轻量操作 main_loop_->Init(); // 13. 执行主部件创建回调:若存在自定义闭包, 传入 BrowserMainParts 实例执行 // 此时 BrowserMainParts 已创建, 可通过其访问浏览器核心组件接口 if (created_main_parts_closure) { std::move(created_main_parts_closure).Run(main_loop_->parts()); } // 14. 早期初始化:执行核心组件的前置初始化(如沙箱, Mojo IPC, Zygote 进程等) // 返回值 >0 表示初始化失败, 需提前退出 const int early_init_error_code = main_loop_->EarlyInitialization(); if (early_init_error_code > 0) { // 失败时创建"早期关闭"专用消息循环(确保资源正常释放, 避免崩溃) main_loop_->CreateMessageLoopForEarlyShutdown(); return early_init_error_code; // 返回错误码, 终止初始化流程 } // 15. 初始化 UI 工具包(如 Aura, Views 等):必须在使用消息循环或显示 UI 前完成 // 工具包提供窗口管理, 控件渲染, 事件处理等基础 UI 能力, 初始化失败则退出 if (!main_loop_->InitializeToolkit()) { main_loop_->CreateMessageLoopForEarlyShutdown(); return 1; } // 16. 主消息循环创建前置操作:初始化消息循环依赖的组件(如线程本地存储, 任务调度器) main_loop_->PreCreateMainMessageLoop(); // 17. 创建主消息循环:启动主线程的消息泵(如 Windows 的 GetMessage, POSIX 的 epoll) // 主消息循环是浏览器的"心脏", 负责处理 UI 事件, 网络回调, 定时任务等 main_loop_->CreateMainMessageLoop(); // 18. 主消息循环创建后置操作:注册消息处理回调, 启动辅助线程等 main_loop_->PostCreateMainMessageLoop(); // 警告:若收到 WM_ENDSESSION(Windows 系统关机/注销事件), 栈上创建的对象不会被析构 // 注意:若需在关机时执行清理逻辑, 需将代码添加到 browser_shutdown::Shutdown 或 // BrowserProcess::EndSession 中(确保关机流程能触发) // 19. 初始化输入方法框架:支持输入法切换, 文本输入, 候选词显示等功能 // 必须在 UI 工具包初始化后执行, 依赖窗口系统的输入事件接口 ui::InitializeInputMethod(); } // 20. 创建启动任务队列:将后续初始化任务(如加载扩展, 恢复标签页, 启动网络服务)赞赏
- [原创]一个 ELF 文件的运行 9027
- [原创]capstone学习: 反汇编器如何实现的 5748
- [原创]chromium 的启动 1147
- [原创]ptrace学习: 阅读 lldb 相关源码 1832
- [原创] QBDI 源码阅读笔记 7919