轉自:http://blog.csdn.net/kuerjinjin/article/details/43937345
簡介
眾所周知chromium項目無比巨大,想去快速的了解,調試並添加自己想要的功能,學會使用chromium中的LOG可以使你省很多事兒!
1.從content shell開始
多數人首次接觸chromium都感覺這個項目太過於龐大,總是有無從下手的感腳;
如果我們想拋開它原有的界面單純的去了解一下它怎么顯示網頁的?那么通過content api來了解chromium是一個不錯的選擇。
項目解決方案生成成功以后,我們可以從src\content\content_shell_and_tests.sln開始,設置content_shell項目為“啟動項目”開始編譯調試,具體打開content_shell_lib項目了解;界面很簡單,界面上的簡單布局我們可以從src\content\shell\browser\shell_views.cc了解到。
我們可以自己去改一下看看效果,比如改一下初始的窗口位置大小:
修改PlatformCreateWindow方法中的params.bounds
params.bounds = gfx::Rect(40, 40, width, height);
- 1
找到src\content\shell\browser\shell.cc修改一下:
const int Shell::kDefaultTestWindowWidthDip = GetSystemMetrics(SM_CXSCREEN) - 160; const int Shell::kDefaultTestWindowHeightDip = GetSystemMetrics(SM_CYSCREEN) - 160;
- 1
- 2
編譯完成后看看是不是順眼多了?首次啟動要顯示的網頁我們也可以從src\content\shell\browser\shell_browser_main_parts.cc
的GetStartupURL方法做個修改,默認沒有參數的時候打開的網頁:
if (args.empty()) return GURL("http://www.baidu.com/");
- 1
- 2
再或者我們修改一下用戶數據的位置src\content\shell\browser\shell_browser_context.cc的InitWhileIOAllowed方法中:
CHECK(PathService::Get(base::DIR_MODULE, &path_));
- 1
將用戶數據直接保存在程序目錄等等;當然這些都不是重點,說這么多只是讓你對content shell有一個初步的了解。
補充幾點:
1.為了方便查看生成后的文件可以單獨設置生成目錄為src\out_content_shell
python src\build\gyp_chromium -Goutput_dir=out_content_shell
- 1
2.基本的依賴文件就只有“content_shell.exe”,“content_shell.pak”和“icudtl.dat”。
當然你如果把原有的views\controls以及開發者工具等用到的資源等去掉的話content_shell.pak也可以進一步干掉;如果要保留對一些HTML5特性的支持的話d3dcompiler_46.dll,ffmpegsumo.dll,libEGL.dll ,libGLESv2.dll 也是可以保留的!
2.初步了解chromium中的LOG
content_shell.exe每次啟動都會生成一個content_shell.log,這個文件的生成我們可以看一下src\content\shell\app\shell_main_delegate.cc中的InitLogging方法,這里就LOG的初始化有明確的演示:
base::FilePath log_filename; PathService::Get(base::DIR_EXE, &log_filename); log_filename = log_filename.AppendASCII("content_shell.log"); logging::LoggingSettings settings; // log輸出的位置 settings.logging_dest = logging::LOG_TO_ALL; // log的文件名 settings.log_file = log_filename.value().c_str(); // 是否鎖定log文件 settings.delete_old = logging::DELETE_OLD_LOG_FILE; logging::InitLogging(settings); //log是否記錄 [ 進程id,線程id,時間戳,精確時間 ] logging::SetLogItems(true, true, true, true); // 是否彈窗顯示FATAL錯誤 logging::SetShowErrorDialogs(true); // 設置斷言錯誤回調函數,當Assert失敗的時候會調用這個函數 //logging::SetLogAssertHandler(MyLogAssertHandler); // 設置log回調函數,當輸出log的時候會調用這個函數 //logging::SetLogMessageHandler(MyLogMessageHandler);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3.我們要學會使用的幾個常用的LOG宏
1)LOG宏:
LOG就像c++標准庫的輸出一樣重載<<,它有幾個常用的等級,
像”VERBOSE“,“INFO”, “WARNING”, “ERROR”, “FATAL”,”NUM_SEVERITIES“等
比如”FATAL”LOG會觸發一個斷點,並打印出棧回溯信息。
LOG(INFO) << "info等級 = " << logging::LOG_INFO; LOG(WARNING) << "WARNING等級 = " << logging::LOG_WARNING; LOG(ERROR) << "ERROR等級 = " << logging::LOG_ERROR; LOG(FATAL) << "FATAL等級 = " << logging::LOG_FATAL;
- 1
- 2
- 3
- 4
使用LOG_IF宏可以在表達式條件為真的情況下才輸出log:
int if_int = 5; LOG_IF(INFO, if_int < 10 ) << "if_int < 10";
- 1
- 2
CHECK宏在表達式為假的情況下執行LOG(FATAL)的效果,
如果沒有附加調試器,還會生成一個crash dump。
//CHECK宏,條件失敗則產生一個LOG(FATAL) CHECK(0);
- 1
- 2
2)DLOG宏:
DLOG跟LOG類似,不同的是DLOG只在DEBUG模式下才生效,
在非DEBUG模式下,這部分代碼都不會被編譯進程序。
DLOG(INFO) << "DLOG onlg debug"; DLOG_IF(INFO, if_int < 10) << "DLOG_IF onlg debug"; LOG_ASSERT(0); DLOG_ASSERT(0);
- 1
- 2
- 3
- 4
3)VLOG宏:
這是一種可以通過命令行參數動態調整輸出log策略的宏,這些宏都是INFO級別的。
4)PLOG宏:
這中宏除了輸出我們指定的輸出信息,后面還附加有系統最后的錯誤信息,
windows上是GetLastError(),POSIX上是errno的值。
TIPS:每個版本的LOG宏可能不一樣,新版本可能都會添加一下東西,具體的詳細英文注釋都可以查看src\base\logging.h
待續……