关于如何使用gdb+gdbserver调试android webkit,请参考这篇文章。按照这种方法,每次启动gdb,都要设置调试符号查找路径,要连着输入好几个gdb命令,对于频繁调试webkit来说,很是麻烦。本文介绍的就是一种偷懒的方法。
好在GDB支持启动文件,可以将gdb命令放在一个GDB启动文件中,然后每次启动GDB时会自动加载它们。GDB的启动文件默认为.gdbinit,也可以在调用GDB时指定启动文件,例如:
gdb -command=mygdbinit x
表示要调试可执行程序x,首先从文件mygdbinit中读取命令。本文选用第二种方法,不想将项目特有的指令影响其它程序的gdb调试。很快就可以写一个启动文件和脚本来减少命令的输入:
# filename: mygdbinit
set solib-absolute-prefix /home/developer/android/out/target/product/generic/symbols/
set solib-search-path /home/developer/android/out/target/product/generic/symbols/system/lib
target remote :5039
#!/bin/bash
./out/host/linux-x86/bin/adb forward tcp:5039 tcp:5039
./prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gdb -command=./mygdbinit out/target/product/generic/symbols/system/bin/app_process
这个脚本在我的机器上工作得很好,但是在其他小组成员上有问题,原因在于每个人的android源码存放的位置并不相同,在mygdbinit中定义了绝对路径并不合适,简单的解决方案是每个人都把上面两个文件稍微修改一下,有没有更好的解决方法呢?
我想到的一个解决方案是定义一个环境变量$ANDROID_SOURCE,指向android源码根目录,问题也随之而来,gdb命令中并不能直接使用系统环境变量。借助于万能的互联网,最终还是找到解决方法,最终脚本如下:
# filename: mygdbinit
define loadsymbols
shell echo set solib-absolute-prefix $ANDROID_SOURCE/out/target/product/generic/symbols/ >/tmp/tmp.webkitsymbolspath
shell echo set solib-search-path $ANDROID_SOURCE/out/target/product/generic/symbols/system/lib >>/tmp/tmp.webkitsymbolspath
source /tmp/tmp.webkitsymbolspath
shell rm /tmp/tmp.webkitsymbolspath
endloadsymbols
target remote :5039
#!/bin/bash
if [ -d $ANDROID_SOURCE ] ; then
echo "ANDROID_SOURCE: $ANDROID_SOURCE"
else
echo "you must define ANDROID_SOURCE environment variable to point your android source"
exit 1
fi$ANDROID_SOURCE/out/host/linux-x86/bin/adb forward tcp:5039 tcp:5039
$ANDROID_SOURCE/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gdb -command=$ANDROID_SOURCE/webkit_gdbinit $ANDROID_SOURCE/out/target/product/generic/symbols/system/bin/app_process
另外在$ANDROID_SOURCE/external/webkit/Tools/gdb/下还有实用的python脚本,可用于gdb调试,打印输出webkit数据类型。
补充:gdb + ddd是一个不错的选择,可以一边调试,一边查看源代码,断点定义也比较直观,虽然比不上Visual Studio这种IDE,但调试还是可以轻松许多。
在研究了chromium for android后,发现其中有几个脚本非常有用,稍加修改后用于android webkit调试:
1、命令行上启动Browser (adb_run_browser)
#!/bin/bash
if [ $# –gt 0 ] ; then
INTENT_ARGS=”-d $1” # e.g. a URL
fi
adb shell am start
-a android.intent.action.VIEW
-n com.android.browser/.BrowserActivity
$INTENT_ARGS
2、命令行上kill掉Browser (adb_kill_browser)
#!/bin/bash
BROWSER_PID_LINES=$(adb shell ps | grep ‘ com.android.browser’)
VAL=$(echo “$BROWSER_PID_LINES” | wc –l)
if [ $VAL –lt 1 ] ; then
echo “Not running Browser.”
else
BROWSER_PID=$(echo $BROWSER_PID_LINES | awk ‘{print $2}’)
if [ “$BROWSER_PID” != "" ] ; then
set –x
adb shell kill $BROWSER_PID
set -
else
echo “Browser does not appear to be running.”
fi
fi