利用Tracing阅读Chromium代码

Chromium中的Tracing工具可以记录每个函数的执行时间,是用来诊断浏览器性能问题的工具。它还有一个意想不到的用处,就是帮我们理解Chromium的代码,因为Tracing会把调用过的函数按照时间轴输出出来,通过Tracing的图形化界面,可以很清楚的明白对象函数之间的调用关系。 components/tracing/tracing_switches.cc代码文件的注释很清楚了介绍了Tracing命令行参数的用法: trace-config-file。这个开关指定Tracing命令行的配置文件,Tracing既可以通过命令行字符串设置配置,也可以通过加载一个配置文件来设置配置。 trace-shutdown。记录浏览器关闭时候到的Tracing信息。 trace-shutdown-file。把trace-shutdown记录的信息保存到一个指定的文件中。 trace-startup。记录浏览器启动时候的Tracing信息。 trace-startup-file。把trace-startup记录的信息保存到一个指定的文件中。 trace-startup-duration。设置trace-startup记录的秒数。 另外在trace-startup、trace-shutdown里面可以设置记录的Tracing类别,比如–trace-startup=base,net,就只会记录base和net类别的Tracing。 比如把以下命令行参数传递给浏览器: 它会记录浏览器启动的时候的Tracing信息,包含browser、content、input、renderer、renderer_host、startup、ui类别,记录10秒的数据,并把数据保存到tracing.json文件中。 然后浏览器地址栏中输入chrome://tracing/,点击左上角的Load按钮,加载我们生成的tracing.json数据文件,然后浏览器就会把数据以图形的样式展现给我们,如下图所示: 图中清楚显示了浏览器启动时做的各种初始化的工作,以及各种工作的先后次序。 Tracing中的数据是根据代码中的TRACE_EVENT宏收集到的: 我们也可以增进自己的数据,宏的第一个参数是类别。 ... Read More | Share it now!

搭建Chromium代码镜像

动机 做Chromium浏览器开发有件比较蛋疼的事情是获取Chromium代码。Chromium代码仓库一是比较大,依赖的东西很多,二是它的服务器都在国外,国内往往连不上。因此我想利用一台能够直接访问chromium.googlesource.com的服务器做为googlesource的镜像,我直接通过镜像来同步代码。 配置镜像服务器 https://chromium.googlesource.com/chromium/src.git是Chromium代码的主仓库,它依赖70多个第三方仓库,最方便快捷的方式就是利用cache-dir机制来一次性获取所有代码仓库。 获取depot_tools Chromium代码都是用depot_tools工具来管理,所以第一步就是要获取这个工具。在/chromium目录里面运行:git... Read More | Share it now!

管理Chromium源代码的利器——depot_tools

由于Chromium项目的代码量巨大,又依赖了很多第三方代码库,所以如何有效的管理这些代码是个难题。Chromium官方提供了一个depot_tools来管理Chromium源代码的工具,官方开发工作流也是基于depot_tools。最初接触depot_tools觉得它很难用,最近研究了depot_tools的代码,发现掌握了它能够让我们事半功倍。 配置depot_tools 因为我是在Windows上开发Chromium,所以只介绍Windows上配置depot_tools的流程。 根据https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up的介绍,从这里https://src.chromium.org/svn/trunk/tools/depot_tools.zip... Read More | Share it now!

chromium browser端启动逻辑

chromium浏览器的入口是chrome_exe_main_win.cc,wWinMain主函数就在这个文件里。wWinMain里面的逻辑很简单,里面MainDllLoader会根据命令行type参数去加载chrome.dll或者chrome_child.dll,然后调用dll中的ChromeMain函数。   在ChromeMain中会创建ChromeMainDelegate对象,生成ContentMainParams传递给content::ContentMain,再通过ContentMainParams去初始化ContentMainRunner对象。 ChromeMainDelegate继承自content::ContentMainDelegate,主要是在围绕Sandbox初始化的前后做一些工作,另外创建一些ChromeContentBrowserClient,ChromeContentRendererClient,ChromeContentPluginClient,ChromeContentUtilityClient的对象,浏览器的更多逻辑都在ChromeContent*Client这些对象中。此外还调用content::SetContentClient设置ChromeContentClient。 ChromeMainDelegate的那些方法都会在ContentMainRunner中陆续调用到。 在ContentMainRunner::Initialize函数中又调用ChromeMainDelegate::BasicStartupComplete。ChromeMainDelegate::BasicStartupComplete做一些初始化工作并调用content::SetContentClient。 ContentMainRunner::Initialize又调用ContentClientInitializer通过ChromeMainDelegate去CreateContent*Client。然后ContentMainRunner::Initialize继续做一些初始化工作。 ContentMainRunner::Initialize中接着调用ChromeMainDelegate::PreSandboxStartup。 PreSandboxStartup中初始化UserDataDir。初始化logging系统。 ContentMainRunner::Initialize中接着初始化Sandbox。初始化工作完成。 然后调用ContentMainRunner::Run,在run里面调用RunNamedProcessTypeMain。RunNamedProcessTypeMain先调用ChromeMainDelegate::RunProcess,然后根据进程类型调用对应的BrowserMain,RendererMain,PluginMain,GpuMain等等。 在BrowserMain中,有个BrowserMainRunner,跟ContentMainRunner类似。BrowserMainRunner::Initialize中根据MainFunctionParams创建BrowserMainLoop。BrowserMainLoop::Init中调用ChromeContentBrowserClient::CreateBrowserMainParts创建BrowserMainParts*。同时还在这里Initialize创建其他线程消息循环。 最后BrowserMainRunnerImpl::Run调用BrowserMainLoop::RunMainMessageLoopParts开始了UI线程的循环。 ChromeContentBrowserClient是浏览器browser逻辑的枢纽。ChromeContentBrowserClient::CreateBrowserMainParts里面创建BrowserMainParts。BrowserMainParts又可以添加其他的ChromeBrowserMainExtraPartsViews,ChromeBrowserMainExtraPartsAsh,ChromeBrowserMainExtraPartsAura对象,这些对象封装的逻辑在BrowserMainRunner里面中被调用执行。 ChromeBrowserMainParts继承自BrowserMainParts,它是个非常总要的类。它创建了BrowserProcessImpl、StartupBrowserCreator、ChromeProcessSingleton、Profile、PrefService等对象。BrowserProcessImpl创建了各种Manager,Service,还有IO线程。StartupBrowserCreator,StartupBrowserCreatorImpl则是开始创建一个Browser,并初始化Profile。 Profile,ProfileImpl继承自content::BrowserContext,对应着browser回话上下文信息和用户配置信息。PrefService则是能把Profile里面的状态增删改查并保存到文件中。 OffTheRecordProfileImpl也是继承自Profile,它是用于隐身模式的浏览器上下文和用户配置信息。 WebContents代表着浏览器tab页中渲染出来的网页。WebContentsImpl则进一步继承了更多的网页方面的操控。Browser则是继承自WebContentsDelegate,它会收到来自WebContents的变化并做出响应。 ... Read More | Share it now!

代码大小查看器CodeSizeViewer

之前参加一个项目,就是精简浏览器的体积。把chromium浏览器某些不重要或者不常用的部分去掉,以达到减少体积的效果。但是面对chromium这个山一样的代码仓库,一开始不知道该精简哪部分才有明显效果。 后来想了一个办法,利用DIA(Debug... Read More | Share it now!

chromium开发设置代理

在中国,由于某些客观原因,经常无法访问google服务。在做chromium开发的时候,depot_tools工具经常无法正常运行,用git或者svn也不能从服务器获取到代码。 如果有vpn,开启vpn就好了。但是公司内部偏偏又不能使用vpn。不过路并未堵死,我们可以使用http代理来访问google服务。 depot_tools代理 运行gclient... Read More | Share it now!