调试 webkit第一步

准备

  在开始之前,要按照chromium官方网站的做法:准备好开发环境,下载代码等,具体请参见: windows编译指南

  用webkit.org的代码来调试和熟悉webkit,在windows上有点困难,查了不少资料,自己也想了些办法,后来发现chromium提供了一个content_shell项目可以让初学者熟悉webkit;打开chrome解决方案(在src/chrome目录下),找到content_shell,并设为启动项目。如下图:


设置调试参数

content_shell项目默认也是多进程的,为了更好的熟悉webkit,建议用单进程来调试,使用如下参数即可: --user-data-dir=c:\tmp\my_debug_profile  --single-process  --renderer-startup-dialog  --no-sandbox,当然你可以改动相关的目录。如下图所示:


 

设置断点和调试:

用vs2010打开page.cpp文件,在src/third_party/webkit/source/webcore/page目录下,找到page类的构造函数:
Page::Page(PageClients& pageClients)
    : m_chrome(Chrome::create(this, pageClients.chromeClient))
    , m_dragCaretController(DragCaretController::create())
#if ENABLE(DRAG_SUPPORT)
    , m_dragController(DragController::create(this, pageClients.dragClient))
#endif
    , m_focusController(FocusController::create(this))
#if ENABLE(CONTEXT_MENUS)
    , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
#endif
#if ENABLE(INSPECTOR)
    , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
#endif
#if ENABLE(POINTER_LOCK)
    , m_pointerLockController(PointerLockController::create(this))
#endif
    , m_settings(Settings::create(this))
    , m_progress(ProgressTracker::create())
    , m_backForwardController(BackForwardController::create(this, pageClients.backForwardClient))
    , m_theme(RenderTheme::themeForPage(this))
    , m_editorClient(pageClients.editorClient)
    , m_validationMessageClient(pageClients.validationMessageClient)
    , m_subframeCount(0)
    , m_openedByDOM(false)
    , m_tabKeyCyclesThroughElements(true)
    , m_defersLoading(false)
    , m_defersLoadingCallCount(0)
    , m_inLowQualityInterpolationMode(false)
    , m_cookieEnabled(true)
    , m_areMemoryCacheClientCallsEnabled(true)
    , m_mediaVolume(1)
    , m_pageScaleFactor(1)
    , m_deviceScaleFactor(1)
    , m_suppressScrollbarAnimations(false)
    , m_didLoadUserStyleSheet(false)
    , m_userStyleSheetModificationTime(0)
    , m_group(0)
    , m_debugger(0)
    , m_customHTMLTokenizerTimeDelay(-1)
    , m_customHTMLTokenizerChunkSize(-1)
    , m_canStartMedia(true)
    , m_viewMode(ViewModeWindowed)
    , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
    , m_timerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval())
    , m_isEditable(false)
    , m_isOnscreen(true)
#if ENABLE(PAGE_VISIBILITY_API)
    , m_visibilityState(PageVisibilityStateVisible)
#endif
    , m_displayID(0)
    , m_layoutMilestones(0)
    , m_isCountingRelevantRepaintedObjects(false)
#ifndef NDEBUG
    , m_isPainting(false)
#endif
    , m_alternativeTextClient(pageClients.alternativeTextClient)
    , m_scriptedAnimationsSuspended(false)
{
    ASSERT(m_editorClient);

    if (!allPages) {
        allPages = new HashSet<Page*>;
        
        networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged);
    }

    ASSERT(!allPages->contains(this));
    allPages->add(this);

#ifndef NDEBUG
    pageCounter.increment();
#endif
}
在红色标记处设置断点,你也可以在该函数的其他地方设置断点,ok,按F5就可以看到如下结果了,一个调用堆栈的copy:

 	webkit.dll!WebCore::Page::Page(WebCore::Page::PageClients & pageClients)  行 152	C++
 	webkit.dll!WebKit::WebViewImpl::WebViewImpl(WebKit::WebViewClient * client)  行 450 + 0x26 字节	C++
 	webkit.dll!WebKit::WebView::create(WebKit::WebViewClient * client)  行 264 + 0x29 字节	C++
 	content.dll!content::RenderViewImpl::Initialize(content::RenderViewImplParams * params)  行 711 + 0x30 字节	C++
 	content.dll!content::RenderViewImpl::Create(int opener_id, const content::RendererPreferences & renderer_prefs, const WebPreferences & webkit_prefs, base::RefCountedData<int> * counter, int routing_id, int surface_id, __int64 session_storage_namespace_id, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & frame_name, bool is_renderer_created, bool swapped_out, int next_page_id, const WebKit::WebScreenInfo & screen_info, AccessibilityMode accessibility_mode, bool allow_partial_swap)  行 931	C++
 	content.dll!content::RenderThreadImpl::OnCreateNewView(const ViewMsg_New_Params & params)  行 1207 + 0xca 字节	C++
 	content.dll!DispatchToMethod<content::RenderThreadImpl,void (__thiscall content::RenderThreadImpl::*)(ViewMsg_New_Params const &),ViewMsg_New_Params>(content::RenderThreadImpl * obj, void (const ViewMsg_New_Params &)* method, const Tuple1<ViewMsg_New_Params> & arg)  行 546 + 0xf 字节	C++
 	content.dll!ViewMsg_New::Dispatch<content::RenderThreadImpl,content::RenderThreadImpl,void (__thiscall content::RenderThreadImpl::*)(ViewMsg_New_Params const &)>(const IPC::Message * msg, content::RenderThreadImpl * obj, content::RenderThreadImpl * sender, void (const ViewMsg_New_Params &)* func)  行 785 + 0x82 字节	C++
 	content.dll!content::RenderThreadImpl::OnControlMessageReceived(const IPC::Message & msg)  行 1179 + 0x84 字节	C++
 	content.dll!content::ChildThread::OnMessageReceived(const IPC::Message & msg)  行 269 + 0x13 字节	C++
 	ipc.dll!IPC::ChannelProxy::Context::OnDispatchMessage(const IPC::Message & message)  行 261 + 0x18 字节	C++
>	ipc.dll!base::internal::RunnableAdapter<void (__thiscall IPC::ChannelProxy::Context::*)(IPC::Message const &)>::Run(IPC::ChannelProxy::Context * object, const IPC::Message & a1)  行 190 + 0x21 字节	C++
 	ipc.dll!base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__thiscall IPC::ChannelProxy::Context::*)(IPC::Message const &)>,void __cdecl(IPC::ChannelProxy::Context * const &,IPC::Message const &)>::MakeItSo(base::internal::RunnableAdapter<void (__thiscall IPC::ChannelProxy::Context::*)(IPC::Message const &)> runnable, IPC::ChannelProxy::Context * const & a1, const IPC::Message & a2)  行 900	C++
 	ipc.dll!base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void (__thiscall IPC::ChannelProxy::Context::*)(IPC::Message const &)>,void __cdecl(IPC::ChannelProxy::Context *,IPC::Message const &),void __cdecl(IPC::ChannelProxy::Context *,IPC::Message)>,void __cdecl(IPC::ChannelProxy::Context *,IPC::Message const &)>::Run(base::internal::BindStateBase * base)  行 1257 + 0x2a 字节	C++
 	base.dll!base::Callback<void __cdecl(void)>::Run()  行 396 + 0xe 字节	C++
 	base.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task)  行 486	C++
 	base.dll!base::MessageLoop::DeferOrRunPendingTask(const base::PendingTask & pending_task)  行 499	C++
 	base.dll!base::MessageLoop::DoWork()  行 688 + 0xc 字节	C++
 	base.dll!base::MessagePumpForUI::DoRunLoop()  行 241 + 0x1d 字节	C++
 	base.dll!base::MessagePumpWin::RunWithDispatcher(base::MessagePump::Delegate * delegate, base::MessagePumpDispatcher * dispatcher)  行 64 + 0xf 字节	C++
 	base.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate)  行 48 + 0x1c 字节	C++
 	base.dll!base::MessageLoop::RunInternal()  行 441 + 0x29 字节	C++
 	base.dll!base::MessageLoop::RunHandler()  行 415	C++
 	base.dll!base::RunLoop::Run()  行 46	C++
 	base.dll!base::MessageLoop::Run()  行 322	C++
 	base.dll!base::Thread::Run(base::MessageLoop * message_loop)  行 160	C++
 	base.dll!base::Thread::ThreadMain()  行 204 + 0x16 字节	C++
 	base.dll!base::`anonymous namespace'::ThreadFunc(void * params)  行 57 + 0xe 字节	C++

从上面的图可以看出:多进程变成了多线程,IPC照样存在,只是在同一个进程中。也验证了一个webview对应一个page的说法。

其中过程,我们可以对照源码细细体会。

相关类图

这里我想介绍chromium webkit port的几个核心抽象类:见图,这样有助于理解



在这个类图中,我们可以看到WebView(WebViewImpl)起到了桥梁的作用,通过它把WebViewClient、ChromeClient和page联系起来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值