Hatena::ブログ(Diary)

ひっそりらぼ

2013-05-21

Blink: Shadow DOMのLayoutTestを実行する

21:45 |

はじめに

BlinkでShadow DOMのLayoutTestを実行する手順のメモです。

仕様

今回は以下の仕様のLayoutTestをピンポイントで実行します。

http://www.w3.org/TR/shadow-dom/

Invoking the cloneNode() method on a ShadowRoot instance must always throw a DATA_CLONE_ERR exception.

テストコード

以下のようなテストコードが用意されています。Shadow Rootに対してcloneNode()すると25番のExceptionが投げられるという単純なテストです。25番は仕様のDATA_CLONE_ERRに対応していて、core/dom/ExceptionCode.hで25と定義されています。


LayoutTest/fast/dom/shadow/shadowroot-clonenode.html

<!DOCTYPE>
<html>
<script src="../../js/resources/js-test-pre.js"></script>

<pre id="console"></pre>

<script>
description('Calling ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception.');

var host = document.createElement('div');
var shadowRoot = host.webkitCreateShadowRoot();
shouldThrow('shadowRoot.cloneNode()', '"Error: DataCloneError: DOM Exception 25"');
</script>
<script src="../../js/resources/js-test-post.js"></script>
</html>

core/dom/ExceptionCode.h

        // Others introduced in HTML5:
        NETWORK_ERR = 19,
        ABORT_ERR = 20,
        URL_MISMATCH_ERR = 21,
        QUOTA_EXCEEDED_ERR = 22,
        TIMEOUT_ERR = 23,
        INVALID_NODE_TYPE_ERR = 24,
        DATA_CLONE_ERR = 25,

LayoutTestの実行

LayoutTestを実行しています。成功します。

> cd src\webkit\tools\layout_tests
> python.exe run_webkit_tests.py --nocheck-sys-deps --debug fast\dom\shadow\shadowroot-clonenode.html
Using port 'chromium-win-win7'
Test configuration: <win7, x86, debug>
Placing test results in F:\ssdcygwin\home\fixme\chrome\src\webkit\Debug\layout-t
est-results
Baseline search path: chromium-win -> generic
Using Debug build
Pixel tests enabled
Regular timeout: 12000, slow test timeout: 60000
Command line: F:\ssdcygwin\home\fixme\chrome\src\build\Debug\DumpRenderTree.exe
-

Found 0 tests; running 0, skipping 0.
No tests to run.

失敗させてみる

shadowroot-clonenode.htmlを適当にいじって、再度実行すると、失敗しました。

> python.exe run_webkit_tests.py --nocheck-sys-deps --debug fast\dom\shadow\shadowroot-conenode.html
Using port 'chromium-win-win7'
Test configuration: <win7, x86, debug>
Placing test results in F:\ssdcygwin\home\fixme\chrome\src\webkit\Debug\layout-
est-results
Baseline search path: chromium-win -> generic
Using Debug build
Pixel tests enabled
Regular timeout: 12000, slow test timeout: 60000
Command line: F:\ssdcygwin\home\fixme\chrome\src\build\Debug\DumpRenderTree.exe
-

Found 1 test; running 1, skipping 0.
Ruby is not installed; can't generate pretty patches.

Running 1 DumpRenderTree.

[1/1] fast/dom/shadow/shadowroot-clonenode.html failed unexpectedly (text diff)

0 tests ran as expected, 1 didn't:


Regressions: Unexpected text-only failures (1)
  fast/dom/shadow/shadowroot-clonenode.html [ Failure ]

失敗のレポートがブラウザに表示されます。リンクをたどることで、失敗の詳細が見れます。

f:id:fixme:20130521213147p:image

2013-04-23

Chromium Code Reading: Experimentalな機能の実装(WebPのAcceptヘッダ送出)

08:02 |

はじめに

Google+を見ていたら、面白そうなポストがありました。

https://plus.google.com/100132233764003563318/posts/KRU6nxp7LXG

Canaryビルドに新しいExperimentalな機能が追加されました。簡単に言うと、画像のリクエスト時にHTTPリクエストのAcceptヘッダにWebP画像をサポートしていることをWebサーバに伝える仕組みです。

今回Canaryに追加されたこの機能は、差分量も小さく、Experimentalな機能の追加方法を学ぶのに最適と思いました。

以下が対象のコードです。

https://codereview.chromium.org/14273007/

  • Issue 13814024: Add a runtime flag in WebRuntimeFeatures to enable 'image/webp' accept header

https://codereview.chromium.org/13814024/

chrome://flags

ChromeURLバーから chrome://flags にアクセスすると、Experimentalな機能のON/OFFができます(以下、スイッチと呼びます)。

最新のChromiumでは以下のような画面が表示されます。

f:id:fixme:20130423215026p:image

スイッチの定義

chrome://flags で表示されるスイッチの説明文はgenerated_resources.grdに定義されています。

src/chrome/app/generated_resources.grd

      <message name="IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_NAME" desc="Title for the flag to enable 'image/webp' in accept header.">
        Enable 'image/webp' accept header
      </message>
      <message name="IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_DESCRIPTION" desc="Description for the flag to enable 'image/webp' in accept header.">
        Enables 'image/webp' accept header in HTTP requests for images, to denote WebP image support.
      </message>

スイッチの特徴がkExperiments定数内に定義されます。

スイッチの説明文、対応OS、スイッチの種類(SINGLE_VALUEはON/OFFのみのスイッチ)など。

const Experiment kExperiments[] = {
[...]
  {
    "enable-webp-in-accept-header",
    IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_NAME,
    IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_DESCRIPTION,
    kOsAll,
    SINGLE_VALUE_TYPE(switches::kEnableWebPInAcceptHeader)
  },
};

初期化

スイッチのデフォルト値はfalseになっていました。

bool RuntimeEnabledFeatures::isWebPInAcceptHeaderEnabled = false;

Blink初期化時に、chrome://flagsで設定されたスイッチの状態取得とランタイム機能郡(WebRuntimeFeatures)にスイッチ状態をセットします。

void RenderThreadImpl::EnsureWebKitInitialized() {
[...]
  WebRuntimeFeatures::enableWebPInAcceptHeader(
      command_line.HasSwitch(switches::kEnableWebPInAcceptHeader));
[...]
}

WebRuntimeFeaturesからRuntimeEnabledFeaturesに委譲されています。

void WebRuntimeFeatures::enableWebPInAcceptHeader(bool enable)
{
    RuntimeEnabledFeatures::setWebPInAcceptHeaderEnabled(enable);
}
class RuntimeEnabledFeatures {
[...]
    static void setWebPInAcceptHeaderEnabled(bool isEnabled) { isWebPInAcceptHeaderEnabled = isEnabled; }
    static bool webPInAcceptHeaderEnabled() { return isWebPInAcceptHeaderEnabled; }

スイッチの利用

ここからは、Experimentalな機能の実装に依存するコードです。

void CachedImage::setCustomAcceptHeader()
{
    if (RuntimeEnabledFeatures::webPInAcceptHeaderEnabled())
        setAccept("image/webp,*/*;q=0.8");
}

余談: バックトレース

バックトレースの取得にcontent shellを使います。content shellとはレンダリングエンジン(Blink)の動作確認に使える軽量ブラウザです。

こんな画面です。質素です。

f:id:fixme:20130423215615p:image

CachedImage::setCustomAcceptHeaderにブレークポイントを設定して、バックトレースを取ってみます。

と、その前に、content_shellプロジェクトのプロパティからコマンドライン引数に「--single-process」オプションを設定しておきます。

これをしておかないとうまくバックトレースが取れません。

バックトレースをざっくり読み解くと、HTMLパース(最近HTMLパースはBackgroundParserでスレッド化された!)、CSSのスタイル解決、画像のロード、キャッシュイメージの生成、を経たことがわかります。

誰が画像を要求したのか、解明してみます。

スタックとレースからStyleResolver::loadPendingImagesを見てみると、CSSのbackground-imageのURLに指定された画像を取得しようとしているようです。

どんな画像?

StyleResolver::loadPendingImageのローカル変数imageValueのm_urlをデバッガで見ると、http://www.google.co.jp/images/srpr/logo4w.png でした。

content shellを起動すると、http://www.google.co.jp/に行くので、Googleトップページのロゴ画像と言うわけです。

>	webkit.dll!WebCore::CachedImage::setCustomAcceptHeader()  行 301	C++
 	webkit.dll!WebCore::CachedImage::CachedImage(const WebCore::ResourceRequest & resourceRequest)  行 62	C++
 	webkit.dll!WebCore::createResource(WebCore::CachedResource::Type type, WebCore::ResourceRequest & request, const WTF::String & charset)  行 73 + 0x29 バイト	C++
 	webkit.dll!WebCore::CachedResourceLoader::loadResource(WebCore::CachedResource::Type type, WebCore::CachedResourceRequest & request, const WTF::String & charset)  行 478 + 0x16 バイト	C++
 	webkit.dll!WebCore::CachedResourceLoader::requestResource(WebCore::CachedResource::Type type, WebCore::CachedResourceRequest & request)  行 405 + 0x20 バイト	C++
 	webkit.dll!WebCore::CachedResourceLoader::requestImage(WebCore::CachedResourceRequest & request)  行 155 + 0x12 バイト	C++
 	webkit.dll!WebCore::CSSImageValue::cachedImage(WebCore::CachedResourceLoader * loader)  行 79 + 0x16 バイト	C++
 	webkit.dll!WebCore::StyleResolver::loadPendingImage(WebCore::StylePendingImage * pendingImage)  行 4248 + 0xc バイト	C++
 	webkit.dll!WebCore::StyleResolver::loadPendingImages()  行 4285 + 0x1b バイト	C++
 	webkit.dll!WebCore::StyleResolver::loadPendingResources()  行 4360	C++
 	webkit.dll!WebCore::StyleResolver::applyMatchedProperties(const WebCore::StyleResolver::MatchResult & matchResult, const WebCore::Element * element)  行 1915	C++
 	webkit.dll!WebCore::StyleResolver::styleForElement(WebCore::Element * element, WebCore::RenderStyle * defaultParent, WebCore::StyleSharingBehavior sharingBehavior, WebCore::RuleMatchingBehavior matchingBehavior, WebCore::RenderRegion * regionForStyling)  行 1010	C++
 	webkit.dll!WebCore::Element::styleForRenderer()  行 1372 + 0x26 バイト	C++
 	webkit.dll!WebCore::NodeRenderingContext::createRendererForElementIfNeeded()  行 247 + 0xc バイト	C++
 	webkit.dll!WebCore::Element::createRendererIfNeeded()  行 1263 + 0x24 バイト	C++
 	webkit.dll!WebCore::Element::attach()  行 1274	C++
 	webkit.dll!WebCore::executeTask(WebCore::HTMLConstructionSiteTask & task)  行 100 + 0x20 バイト	C++
 	webkit.dll!WebCore::HTMLConstructionSite::executeQueuedTasks()  行 143 + 0x12 バイト	C++
 	webkit.dll!WebCore::HTMLTreeBuilder::constructTree(WebCore::AtomicHTMLToken * token)  行 379	C++
 	webkit.dll!WebCore::HTMLDocumentParser::constructTreeFromCompactHTMLToken(const WebCore::CompactHTMLToken & compactToken)  行 617	C++
 	webkit.dll!WebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> popChunk)  行 428	C++
 	webkit.dll!WebCore::HTMLDocumentParser::pumpPendingSpeculations()  行 485	C++
 	webkit.dll!WebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> chunk)  行 334	C++
 	webkit.dll!WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()(const WTF::WeakPtr<WebCore::HTMLDocumentParser> & c, WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> p1)  行 254 + 0x24 バイト	C++
 	webkit.dll!WTF::BoundFunctionImpl<WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void __cdecl(WTF::WeakPtr<WebCore::HTMLDocumentParser>,WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()()  行 523	C++
 	webkit.dll!WTF::Function<void __cdecl(void)>::operator()()  行 704 + 0x1a バイト	C++
 	webkit.dll!WTF::callFunctionObject(void * context)  行 62	C++
 	glue.dll!base::internal::RunnableAdapter<void (__cdecl*)(void *)>::Run(void * const & a1)  行 171 + 0x18 バイト	C++
 	glue.dll!base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void * const &)>::MakeItSo(base::internal::RunnableAdapter<void (__cdecl*)(void *)> runnable, void * const & a1)  行 872	C++
 	glue.dll!base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void *),void __cdecl(void *)>,void __cdecl(void *)>::Run(base::internal::BindStateBase * base)  行 1173 + 0x19 バイト	C++
 	base.dll!base::Callback<void __cdecl(void)>::Run()  行 396 + 0xe バイト	C++
 	base.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task)  行 476	C++
 	base.dll!base::MessageLoop::DeferOrRunPendingTask(const base::PendingTask & pending_task)  行 489	C++
 	base.dll!base::MessageLoop::DoWork()  行 669 + 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()  行 431 + 0x29 バイト	C++
 	base.dll!base::MessageLoop::RunHandler()  行 405	C++
 	base.dll!base::RunLoop::Run()  行 46	C++
 	base.dll!base::MessageLoop::Run()  行 312	C++
 	base.dll!base::Thread::Run(base::MessageLoop * message_loop)  行 153	C++
 	base.dll!base::Thread::ThreadMain()  行 197 + 0x16 バイト	C++
 	base.dll!base::`anonymous namespace'::ThreadFunc(void * params)  行 57 + 0xe バイト	C++
 	kernel32.dll!751c33aa() 
void StyleResolver::loadPendingImages()
{
    if (m_state.pendingImageProperties().isEmpty())
        return;

    PendingImagePropertyMap::const_iterator::Keys end = m_state.pendingImageProperties().end().keys();
    for (PendingImagePropertyMap::const_iterator::Keys it = m_state.pendingImageProperties().begin().keys(); it != end; ++it) {
        CSSPropertyID currentProperty = *it;

        switch (currentProperty) {
        case CSSPropertyBackgroundImage: {
            for (FillLayer* backgroundLayer = m_state.style()->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
                if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage())
                    backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image())));
            }
            break;
        }
PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage)
{
    CachedResourceLoader* cachedResourceLoader = m_state.document()->cachedResourceLoader();

    if (pendingImage->cssImageValue()) {
        CSSImageValue* imageValue = pendingImage->cssImageValue();
        return imageValue->cachedImage(cachedResourceLoader);
    }

2013-04-19

Chromeにはじめて取り込まれたパッチ

23:09 |

記念すべき第1号です。

https://chromium.googlesource.com/chromium/src/+/15fc083b4a23e23417a6bf71f38e2f7966908590

単なるtypoの修正ですが、LGTM(Looks Good To Me)をもらった時は嬉しかったです。

Botビルドとテストを走らせる様子も体験してみると楽しかったです。

https://codereview.chromium.org/14145003/

https://chromium-status.appspot.com/cq/yoshinori.sano%40gmail.com/14145003/6001

2013-04-14

Visual StudioでChromeの動作を見る: Blinkの初期化処理やイベントリスナーのバックトレース取得

00:27 |

はじめに

Visual Studio 2010 ExpressでChromeビルドできるようになったので、次はデバッグを試してみました。

今回は、こちらのドキュメントを参考にしました。

http://www.chromium.org/developers/how-tos/debugging

手順

1. chrome/chrome.slnを開きます。

2. Debug版のChrome.exeをVisual Studioビルドします。

3. ソリューションエクスプローラから「chrome」を右クリックし、「スタートアッププロジェクトに設定」を選択します。

4. 「chrome」プロジェクト -> プロパティ -> デバッグ -> コマンド引数に「--single-process」を指定します。

5. 「webkit」プロジェクト -> 「src」->「WebKit.cpp」(third_party/WebKit/Source/WebKit/chromium/src/WebKit.cpp)を開きます。

6. 「void initialize(Platform* webKitPlatformSupport)」の関数の先頭にブレークポイントを設定します。

7. デバッグを開始します。

バックトレース

以下の呼び出し履歴(バックトレース)が得られます。

 	webkit.dll!WebKit::initialize(WebKit::Platform * webKitPlatformSupport)  行 114	C++
>	content.dll!content::RenderThreadImpl::EnsureWebKitInitialized()  行 628 + 0x17 バイト	C++
 	content.dll!content::RenderThreadImpl::OnCreateNewView(const ViewMsg_New_Params & params)  行 1152 + 0xf バイト	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)  行 790 + 0x82 バイト	C++
 	content.dll!content::RenderThreadImpl::OnControlMessageReceived(const IPC::Message & msg)  行 1140 + 0x84 バイト	C++
 	content.dll!content::ChildThread::OnMessageReceived(const IPC::Message & msg)  行 272 + 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)  行 476	C++
 	base.dll!base::MessageLoop::DeferOrRunPendingTask(const base::PendingTask & pending_task)  行 489	C++
 	base.dll!base::MessageLoop::DoWork()  行 669 + 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()  行 431 + 0x29 バイト	C++
 	base.dll!base::MessageLoop::RunHandler()  行 405	C++
 	base.dll!base::RunLoop::Run()  行 46	C++
 	base.dll!base::MessageLoop::Run()  行 312	C++
 	base.dll!base::Thread::Run(base::MessageLoop * message_loop)  行 153	C++
 	base.dll!base::Thread::ThreadMain()  行 197 + 0x16 バイト	C++
 	base.dll!base::`anonymous namespace'::ThreadFunc(void * params)  行 57 + 0xe バイト	C++
 	kernel32.dll!75cf33aa() 	

このバックトレースだけでも、chromeレイヤー構造が見えてきました。

ChromeレンダリングエンジンはWebKitからフォークしたBlinkに切り替わっていますが、名前はまだWebKitのままのようです。

base.dll -> ipc.dll -> content.dll -> webkit.dll


あと、試しに、イベントリスナーっぽいクラス(EventListenerWrapper)のコンストラクタブレークポイントを置いて、chromeで新しいタブを開くと、以下のバックトレースが得られました。先ほどとは違い、HTMLDocumentParserやWebDOMEventListenerが登場しました。

このようにバックトレースに出てくる関数を中心に攻めていくと、chromeの内部の仕組みを効率的に理解できそうです。

>	webkit.dll!WebKit::EventListenerWrapper::EventListenerWrapper(WebKit::WebDOMEventListener * webDOMEventListener)  行 48	C++
 	webkit.dll!WebKit::WebDOMEventListenerPrivate::createEventListenerWrapper(const WebKit::WebString & eventType, bool useCapture, WebCore::EventTarget * target)  行 52 + 0x28 バイト	C++
 	webkit.dll!WebKit::WebDOMEventListener::createEventListenerWrapper(const WebKit::WebString & eventType, bool useCapture, WebCore::EventTarget * target)  行 59	C++
 	webkit.dll!WebKit::WebNode::addEventListener(const WebKit::WebString & eventType, WebKit::WebDOMEventListener * listener, bool useCapture)  行 186 + 0x1d バイト	C++
 	chrome.dll!autofill::PageClickTracker::DidFinishDocumentLoad(WebKit::WebFrame * frame)  行 95 + 0x65 バイト	C++
 	content.dll!content::RenderViewImpl::didFinishDocumentLoad(WebKit::WebFrame * frame)  行 3681 + 0x52 バイト	C++
 	webkit.dll!WebKit::FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()  行 408 + 0x27 バイト	C++
 	webkit.dll!WebCore::FrameLoader::finishedParsing()  行 688 + 0x15 バイト	C++
 	webkit.dll!WebCore::Document::finishedParsing()  行 4345	C++
 	webkit.dll!WebCore::HTMLConstructionSite::finishedParsing()  行 343 + 0x18 バイト	C++
 	webkit.dll!WebCore::HTMLTreeBuilder::finished()  行 2831	C++
 	webkit.dll!WebCore::HTMLDocumentParser::end()  行 766	C++
 	webkit.dll!WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()  行 777	C++
 	webkit.dll!WebCore::HTMLDocumentParser::prepareToStopParsing()  行 214	C++
 	webkit.dll!WebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> popChunk)  行 453 + 0xf バイト	C++
 	webkit.dll!WebCore::HTMLDocumentParser::pumpPendingSpeculations()  行 485	C++
 	webkit.dll!WebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> chunk)  行 334	C++
 	webkit.dll!WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()(const WTF::WeakPtr<WebCore::HTMLDocumentParser> & c, WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> p1)  行 254 + 0x24 バイト	C++
 	webkit.dll!WTF::BoundFunctionImpl<WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void __cdecl(WTF::WeakPtr<WebCore::HTMLDocumentParser>,WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()()  行 523	C++
 	webkit.dll!WTF::Function<void __cdecl(void)>::operator()()  行 704 + 0x1a バイト	C++
 	webkit.dll!WTF::callFunctionObject(void * context)  行 62	C++
 	glue.dll!base::internal::RunnableAdapter<void (__cdecl*)(void *)>::Run(void * const & a1)  行 171 + 0x18 バイト	C++
 	glue.dll!base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void * const &)>::MakeItSo(base::internal::RunnableAdapter<void (__cdecl*)(void *)> runnable, void * const & a1)  行 872	C++
 	glue.dll!base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void *),void __cdecl(void *)>,void __cdecl(void *)>::Run(base::internal::BindStateBase * base)  行 1173 + 0x19 バイト	C++
 	base.dll!base::Callback<void __cdecl(void)>::Run()  行 396 + 0xe バイト	C++
 	base.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task)  行 476	C++
 	base.dll!base::MessageLoop::DeferOrRunPendingTask(const base::PendingTask & pending_task)  行 489	C++
 	base.dll!base::MessageLoop::DoWork()  行 669 + 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()  行 431 + 0x29 バイト	C++
 	base.dll!base::MessageLoop::RunHandler()  行 405	C++
 	base.dll!base::RunLoop::Run()  行 46	C++
 	base.dll!base::MessageLoop::Run()  行 312	C++
 	base.dll!base::Thread::Run(base::MessageLoop * message_loop)  行 153	C++
 	base.dll!base::Thread::ThreadMain()  行 197 + 0x16 バイト	C++
 	base.dll!base::`anonymous namespace'::ThreadFunc(void * params)  行 57 + 0xe バイト	C++
 	kernel32.dll!75cf33aa() 	

2013-04-13

chromeにパッチを投げてレビューを受けるまでのワークフロー

12:18 |

はじめに

chromeWebSocketのコードを読んでいたら、コメントにtypoを発見しました。

せっかくなので、パッチを作成してレビューを受けられる状態までもっていきました。

一連のワークフローは手順の通りでできました。

http://www.chromium.org/developers/contributing-code

実際にやってみて、パッチの送信からレビュー依頼までのワークフロー(ツールも含む)がよく整っている印象でした。

ワークフロー

ブランチを作成します。

$ git checkout -b fix-typo origin/master
M       net/websockets/websocket_throttle.h
Branch fix-typo set up to track remote branch master from origin.
Switched to a new branch 'fix-typo'

コードを修正します。

$ git diff
diff --git a/net/websockets/websocket_throttle.h b/net/websockets/websocket_throttle.h
index 713e8f8..aff7305 100644
--- a/net/websockets/websocket_throttle.h
+++ b/net/websockets/websocket_throttle.h
@@ -43,7 +43,7 @@ class NET_EXPORT_PRIVATE WebSocketThrottle {

   // Checks sockets waiting in |queue_| and check the socket is the front of
   // every queue for the destination addresses of |socket|.
-  // If so, the socket can resume estabilshing connection, so wake up
+  // If so, the socket can resume establishing connection, so wake up
   // the socket.
   void WakeupSocketIfNecessary();

修正ファイルをコミット対象に加えます。

$ git add net/websockets/websocket_throttle.h

コミットします。

$ git commit

エディタが起動するので、コメントを書きます。

Fix typo in net/websockets/websocket_throttle.h

BUG=231019

「BUG=」に修正対象のバグIDを書きます。

今回はあらかじめ登録しておいたバグIDを指定しました。

typoなのでバグ登録は不要だったかもしれません。

https://code.google.com/p/chromium/issues/detail?id=231019

コメントを保存すると、コミットが完了します。

[fix-typo 6e50384] Fix typo in net/websockets/websocket_throttle.h
 1 files changed, 1 insertions(+), 1 deletions(-)

パッチを送信します。

$ git cl upload

コメントの入力を求められるので、不要なコメント行(#)を削除します。

# Enter a description of the change.
# This will displayed on the codereview site.
# The first line will also be used as the subject of the review.
Fix typo in net/websockets/websocket_throttle.h

BUG=231019

コメントを保存すると、メールとパスワードが聞かれるので入力します。

アップロードが完了すると、レビュー用のURLが発行されます。

 net/websockets/websocket_throttle.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Upload server: https://codereview.chromium.org (change with -s/--server)
Email (login for uploading to https://codereview.chromium.org): xxxxxxx@gmail.com
Password for xxxxxxx@gmail.com:
Saving authentication cookies to /home/ysano/.codereview_upload_cookies
Issue created. URL: https://codereview.chromium.org/14145003
Uploading base file for net/websockets/websocket_throttle.h

発行されたレビュー用URLにアクセスします。

https://codereview.chromium.org/14145003

「Edit Issue」をクリックし、レビュアを割り当てます。

src/net/websockets/OWNERS を見ると、鵜飼さんがあったので、鵜飼さんを割り当てました。

「Publish+Mail Comments」をクリックし、メッセージを書きます。

以上でレビューの依頼が完了しました。