2015一个新的开始

上周提离职了,这周开始休年假。 2012年加入奇虎360,一转眼已是3年多了。毕业同一期进来的同学,还剩下三分之一,有种“知交半零落”的感觉,大家都在各自的人生方向上越走越远。 有很多感慨无处抒发,以后360浏览器就拜托尹大神,何大神了,还有小蔡、涛神。 前段时候,一直很忙,原以为过完年刚来不会很忙的,谁知需求一个接着一个。后来又赶上升级浏览器内核,更是忙的不得了。尹大神跟何大神也是,任劳任怨。现在想想,公司确实挺亏待我们几个的。 一忙起来,博客就好久没更新了。之前我跟自己定下的目标是一个星期至少要更新一次,否则这周就过得太糊涂了,连个总结都没有。 最近业余时间其实一直在研究chromium的ui底层,有些心得。但是要跟向别人表达清楚却比较难,我迫切的需要一种工具来帮我分析与表达软件工程。 我选择了UML。大学里学过UML,只知一点皮毛,但是一直没怎么实践过。现在也正是一个契机把UML运用起来。 我也对未来的生活充满了期望,总之加油,量变产生质变。 ... 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!

c++中的智能指针

内存管理是c++中比较棘手的问题。轻则是内存泄漏,重则是野指针、访问越界而崩溃,我们必须小心翼翼的对待指针。c++写多了,有时候会怀念java,c#这种有垃圾回收机制的语言,它们写出的代码是多么的干净优雅。 以前c++标准库里只有一个auto_ptr的智能指针,它的出现让我眼睛为之一亮,原来c++代码还可以这样管理指针啊。但是auto_ptr适应的场景有限,还有自己本身管理权转移晦涩的问题。 c++的准标准库boost为此准备了一组智能指针,scoped_ptr、socped_array、shared_ptr、shared_array、weak_ptr、intrusive_ptr。开源的浏览器chromium也有自己的智能指针解决方案linked_ptr、scoped_ptr、scoped_refptr、WeakPtr。c++... Read More | Share it now!

chromium中的性能优化工具syzyProf

函数性能分析工具SyzyProf 我先开始介绍SyzyProf。这个工具可以捕获每个线程调用每个函数执行的时间,然后把结果生成一个KCacheGrind能够识别的数据格式文件,然后通过KCacheGrind的展示结果。你就可以知道函数哪个函数执行了次数最多,消耗的时间最多,哪个线程在读写文件,哪个线程在创建窗口界面,而且KCacheGrind以图形的方式显示出函数调用链等信息,非常直观。如图这是我生成CEF自带demo程序的函数调用信息。 其实能够函数性能分析工具已经够多了,比如xperf,AQTime,还有visual... Read More | Share it now!

跨进程的SetParent

以前好像隐约听别人提到一次,一个进程的窗口可以跟另一个进程的窗口设置成父子关系。当时不太相信这样的说法,认为不可能的。真的能够跨进程SetParent吗? 看MSDN,SetParent里面说如果把hWndNewParent参数的值为NULL,则桌面窗口就是新的父窗口。桌面窗口就是在另外的explorer进程里面的,貌似是可以的,但是MSDN里面没有明确表态。今天我自己写了个测试程序,果然可以,真是毁三观啊,进程边界在哪里?跟之前想的完全不一样。 我最近想实现一个双核浏览器,就是在chromium浏览器的基础上加上IE内核,可以在Blink渲染引擎与Trident渲染引擎之间切换。这不是什么新东西了,国内的很多浏览器都实现这个技术,比如360安全浏览器,搜狗浏览器。我也要自己实现一个,虽然是重复的造轮子,但是在造轮子的过程中可以学到很多。 chromium的多进程架构我已经很熟悉了,就是renderer进程只负责渲染出网页,然后发送到browser进程去显示出来,同样browser进程把各种消息转发到renderer进程。IE的多进程架构则不一样,IE则是子进程真正的创建窗口,在窗口里面包了一个Internet... Read More | Share it now!