Windows下調試Chromium及WebRTC源碼的一些心得

這裏記錄一些關於在Windows上調試CEF/Chromium/WebRTC源碼的一些心得體會,也是怕時間久了就忘記了其中一些細節。

因爲經常有需要對CEF以及WebRTC的源碼進行分析和修改,所以修改後如何調試就成了首要解決的問題。CEF,或者說Chromium與普通的小工程不同,他的龐大是衆所周知的。所以爲什麼Google專門創造了GN和ninja。

在編譯了CEF以後,在out目錄下會有各種版本的編譯中間代碼文件、二進制文件等等,包括以下目錄:

Debug_GN_x64\
Debug_GN_x64_sandbox\
Debug_GN_x86\
Debug_GN_x86_sandbox\
Release_GN_x64\
Release_GN_x64_sandbox\
Release_GN_x86\
Release_GN_x86_sandbox\

以 Debug_GN_x86 舉例,這裏面有一個1MB多的 cef.sln文件,如果用Visual Studio 2017打開它,在解決方案列表裏,你會看到一個超級超級長的project列表,整個工程加載也是需要很長的時間。我目前的筆記本是 i7 8550,16G,海康威視SSD,加載速度也是讓我不太能夠忍受的。而且經常動不動Visual Studio 2017就崩潰重啓了。

所以,如果不用 cef.sln,我們怎麼調試CEF以及WebRTC呢?

我這裏提供一種方法,就是代碼的瀏覽、修改使用VS Code或VS 2017(直接打開.h/.cc文件),修改後,使用ninja在命令行中手動編譯,然後把CEF示例程序(例如cefclient.exe)運行起來,之後在Visual Studio 2017中打開需要調試的代碼,設好斷點,之後用 Debug菜單下的 Attach to process 命令,attach到對應的進程上(由於Chromium是多進程架構,所以需要根據調試內容attach到不同的進程)。

如果你打開的源碼正確,斷點也確保可以執行到,且attach到的進程也正確,那麼當你在CEF中執行相應功能時候,就會發現在Visual Studio 2017中,你剛纔設置的斷點生效了。

下面舉個例子,比如我想看一下在CEF中使用js創建一個H.264編碼的視頻流,WebRTC是如何創建和初始化H.264編碼器的,以及編碼視頻幀的函數調用。按照上面介紹的方法,我們需要先找到CEF中,WebRTC H.264編碼器的源碼在哪裏:

\src\third_party\webrtc\modules\video_coding\codecs\h264\h264_encoder_impl.h/.cc

注:由於WebRTC代碼變化頻繁,本文以CEF 3729(對應的WebRTC版本是M74分支)爲藍本介紹。

啓動Visual Studio 2017,打開h264_encoder_impl.cc,並隨便在幾個函數入口設置斷點。例如在 H264EncoderImpl構造函數,InitEncode()、Encode()我設置了3個斷點:

然後在命令行中運行 out\Debug_GN_x86\cefclient.exe,啓動命令行參數我指定的是: 

--enable-media-stream --no-proxy-server --ignore-certificate-errors --enable-logging --v=1

參數說明:

--enable-media-stream:授權CEF可以使用本地攝像頭麥克風設備

--no-proxy-server:防止Debug版本的cefclient崩潰

--ignore-certificate-errors:我用來測試的頁面是https的但是我沒有配置站點證書,用這個來忽略一下

--enable-logging --v=1:啓用詳細日誌。默認會產生在命令行窗口以及產生一個debug.log文件(和cefclient.exe同級目錄下)

更多的啓動參數,可以參考:https://peter.sh/experiments/chromium-command-line-switches/

在啓動的cefclient.exe瀏覽器窗口中,打開用於視頻推流測試網頁,先不要執行推流。

回到Visual Studio 2017,執行 Debug菜單下的Attach to process,會發現進程列表裏有3個cefclient.exe:

視頻的編碼不再主進程(有標題文字的那個),在另外的一個進程中。由於另外的2個進程沒有標題,所以需要逐一試一下。

attach到指定的進程以後,VS2017進入調試模式。現在我們回到網頁,開始執行視頻推流:

按下推流按鈕,果然如我們期望的,在VS2017中,我們剛剛在H264EncoderImpl的構造函數中設置的斷點生效了,程序停留在我們設置的斷點位置,相關變量的值,以及程序調用堆棧,一覽無餘。

F5運行,會發現我們剛纔設置的其他兩處斷點也相繼生效了:

OK,這種調試方法,不需要打開整個sln工程,避免查看龐大的project列表,避免啓動慢、解析慢等問題。缺點是需要你對CEF、WebRTC代碼工程源碼結構有一定的瞭解,以便準確知道你要調試內容的源碼位置並直接打開。

最後介紹一下修改CEF/WebRTC源碼後的編譯方法。

在首次全量編譯CEF的時候,我們一般是使用CEF官網提供的 automate-git.py完成的,這個python腳本集下載、編譯、打包爲一體,在網絡代理(你懂得)強大的情況下,用這個腳本是十分輕鬆方便的。但是如果我們只修改了幾個文件,就不用再動用automate-git.py了,只需要使用 ninja命令來編譯即可。

舉例如下,我們隨便修改一個文件,例如:\src\third_party\webrtc\video\video_stream_encoder.cc,我隨便挑了一個函數 VideoStreamEncoder::ConfigureEncoderOnTaskQueue(),修改了一條日誌語句,加了幾個字符:

修改以後,在命令行窗口中轉到CEF的src目錄下,運行以下命令:

ninja -C out\Debug_GN_x86 cefclient

ninja將會幫我們進行鍼對修改部分的增量編譯。在我機器上,即便只是修改了剛纔那一個地方,用ninja也編譯了幾分鐘……不知道到底是機器性能不行還是真的編的慢……

OK,編譯成功後,再次啓動cefclient.exe(別忘記增加 --enable-logging --v=1),執行視頻推流,然後在cefclient.exe同級目錄下找到debug.log,打開,搜索關鍵字:ConfigureEncoder,會看到,我們剛纔的修改生效了:

當然,直接把源碼拖到VS 2017中調試,不在debug.log中查看也是可以的。

好了,工欲善其事必先利其器,掌握了基本的編譯和調試方法,對CEF/WebRTC代碼的研究和修改、試驗就方便多了。

除此以外,閱讀一下Debugging Chromium on Windows,也會得到不小的收穫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章