從Android 4.4開始,系統的WebView元件就采用了Chromium/Blink引擎。Chromium的代碼及其龐大,了解起來也有些難度。借助于gdb調試,通過跟蹤代碼的運作,列印調用堆棧,有助于了解代碼的執行流程。另外libchromiumwebview.so的編譯連結及其耗時間,是以那種打log的方式除非不得已,還是要盡量少用。雖然Chromium for Android以及Chromium桌面版都采用了多程序模型,但Chromium WebView卻是采用的單程序模型,是以調試上簡單了很多。
下面以Android 5.1為例,調試腳本如下:
#!/bin/bash
# check env setup first
if [ ! "$ANDROID_BUILD_TOP" ]; then
echo "please source build/envsetup.sh to set env var first!"
exit
fi
GDBSERVER_LOG=temp.log
BROWSER_PACKAGE_NAME="com.android.browser"
BROWSER_ACTIVITY="BrowserActivity"
# adbd get root privileges
adb root
sleep
# get pid of browser
PID=$(adb shell ps | grep $BROWSER_PACKAGE_NAME | awk '{print $2}')
echo "pid of $BROWSER_PACKAGE_NAME is $PID"
if [ ! "$PID" ]; then
adb shell am start -n $BROWSER_PACKAGE_NAME/.$BROWSER_ACTIVITY
sleep
PID=$(adb shell ps | grep $BROWSER_PACKAGE_NAME | awk '{print $2}')
fi
# kill gdbserver
gdbserver_pid=$(adb shell ps | grep "gdbserver" | awk '{print $2}')
if [ "$gdbserver_pid" ]; then
adb shell kill $gdbserver_pid
fi
# gdbserver attach browser pid in background
echo "attach pid $PID in background"
(adb shell gdbserver : --attach $PID > $GDBSERVER_LOG >&) &
sleep
touch gdb.init
readonly COMMANDS=gdb.init
echo -n "" > $COMMANDS
echo "ANDROID_BUILD_TOP = $ANDROID_BUILD_TOP"
adb forward tcp: tcp:
echo "file $ANDROID_BUILD_TOP/out/target/product/mako/symbols/system/bin/app_process32" >> $COMMANDS
echo "set solib-absolute-prefix $ANDROID_BUILD_TOP/out/target/product/mako/symbols/system/lib" >> $COMMANDS
echo "set solib-search-path $ANDROID_BUILD_TOP/out/target/product/mako/symbols/system/lib" >> $COMMANDS
echo "target remote :5039" >> $COMMANDS
$ANDROID_TOOLCHAIN/arm-linux-androideabi-gdb -x $COMMANDS &&
# kill gdbserver
gdbserver_pid=$(adb shell ps | grep "gdbserver" | awk '{print $2}')
if [ "x$gdbserver_pid"!="x" ]; then
adb shell kill $gdbserver_pid
fi
echo "done"
在執行這個腳本之前,需要設定一些android源碼build的環境變量。比如為nexus 4 build系統的指令為:
source ./build/envsetup.sh
lunch aosp_mako-userdebug
如果你在調試過程中遇到讨厭的如下中斷錯誤:
Program received signal SIG33, Real-time event
解決方法如下為,在gdb調試符下輸入如下指令:
在下一片文章中,我将會說明如何調試Java部分的代碼。