chrome源码学习之启动流程简介

先说明一下,我这里采用的chrome源代码版本是4.1.249.1064。如果你采用的不是此版本,则可能和我描述的源代码文件名、代码位置不一致,后续关于chrome的文章均采用此版本,不再另作说明。采用此版本没有任何特殊理由,仅仅是当我开始学习chrome的那个时间点的最新版本而已。

另外虽然chrome的版本升级非常快,但其核心体系架构是没有变化的。升级的变更的内容主要体现在下面几个方面:

1.安全性、稳定性、速度提升

2.新功能点增加

3.HTML5相关内容

4.整合集成google自己的产品服务

因此从学习角度看,如果不是特别需要对某些新增加的特性感兴趣,如果重点是想学习其基础体系结构和web核心相关模块,那么选择一个较早的版本来学习反而更好。因为这样代码量少,重点突出,干扰少些。当掌握好基本体系结构后,后续的版本自然就很容易上手了。

下面简要说明chrome的启动流程,这里重点不会分析代码细节,而是快速定位几个比较关键的位置,可以在这些位置设置断点,然后你可以查看调用栈以了解具体的调用流程。这样可以先初步进入开始单步跟踪。

为了便于跟踪说明,请在浏览器选项菜单中将启动的主页地址设置为一个具体地址比如http://www.baidu.com/

注意:因为chrome是多进程结构,所以在调试的时候需要附加到对应的进程才能看到断点效果。如果不想那么麻烦,也可以以单进程模式启动调试,具体是在chrome exe的工程属性中加命令行参数 --single-process。我将以多进程模式为例来讲解。

EXE启动入口

应用程序执行文件的WinMain入口函数在chrome exe工程的chrome_exe_main.cc文件中,在一些初始化代码后,加载

chrome.dll内核文件,代码如下:

...
MainDllLoader* loader = MakeMainDllLoader(); 
int rc = loader->Launch(instance, &sandbox_info);
...

MainDllLoader::Launch的实现在client_util.cc中,其中有代码(…为我忽略掉的代码):

int MainDllLoader::Launch(HINSTANCE instance,
                          sandbox::SandboxInterfaceInfo* sbox_info) {
  ...
  dll_ = Load(&version, &file);
  ...
  DLL_MAIN entry_point =
      reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
  ...
  
  int rc = entry_point(instance, sbox_info, ::GetCommandLineW());
  return OnBeforeExit(rc);
}

通过调用Win32 API GetProcAddress来动态获取chrome.dll中的入口函数“ChromeMain”的地址然后调用进入。

DLL入口函数

chrome.dll的入口函数是ChromeMain,其工程名为chrome_dll。

ChromeMain的实现在chrome_dll_main.cc中:

DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance,
                                 sandbox::SandboxInterfaceInfo* sandbox_info,
                                 TCHAR* command_line) 
{
  ...
  int rv = -1;
  if (process_type == switches::kRendererProcess) {
    rv = RendererMain(main_params);
  } else if (process_type == switches::kExtensionProcess) {
    // An extension process is just a renderer process. We use a different
    // command line argument to differentiate crash reports.
    rv = RendererMain(main_params);
  } else if (process_type == switches::kPluginProcess) {
    rv = PluginMain(main_params);
  } else if (process_type == switches::kUtilityProcess) {
    rv = UtilityMain(main_params);
  } else if (process_type == switches::kProfileImportProcess) {
    ...
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值