WebKit技巧:如何用GDB进行调试
2012-07-22 18:46
260 查看
对于Android中的Webkit(libwebcore.so),因为它是系统底层的库,所以没有办法像App和Frameworks那样直接用Eclipse来调试,因为它们都是C和C++语言,所以对于它来讲只能用GDB来进行调试。
熟悉流程
可以确定一定的代码范围
先是要把手机Browser进程关联到一个端口,再通过adb forward命令把手机的端口与PC的端口相映射,因为PC上的GDB与手机中的GDB Server就是通过这个端口来通信的。手机中运行gdbserver,它会与手机Browser进程通信,也就是与真正的库交互,而PC端运行GDB与带有调试信息的库交互,PC的GDB再通过端口与手机 中的GDB Server通信,这样我们就能够在PC上调试手机中的库了。
映射端口,在PC的Shell中运行
设置手机和GDB Server,打开手机Browser,进入adb shell,用ps命令找到Browser的pid,然后运行
设置PC GDB,要运行源码下的GDB文件
之后,会进行GDB的提示符下面,先加载所要调试的库:
然后开始调试
之后就可以用GDB命令去调试了。
每次调试,gdbserver都要重新设置,因为每次PID都会不一样,而gdb client端刚不需要重复。
为了简化流程,对于gdbserver的设置可以用Shell脚本来做,如下:
可以把这段脚本保存为gdbserver.sh,把其中的路径更换为相应的源码路径即可。每次调试前先运行一次gdbserver.sh,手机端就设置好了。
client端的命令也很长,所以也可以用脚本:
把它保存为gdbclient.sh,运行起来比较方便。
但对于GDB的Promt里面的设置库的过程则必须手动设置了,但所幸Client端不用每次都配置。
h或help 显示帮助信息
q或quit 退出GDB
r或run 运行程序
c或continue 继续运行至下一个断点
s或step 单步跟踪,会进入每一个函数调用
n或next 执行下一步,不会进行函数
ENTER(回车) 重复上一命令
b或break 设置断点
d或delete 删除断点,不带参数则删除所有断点
更详细参考:GDB Documentation
b filename:lineno,如FrameLoader.cpp:1515
b filename:function, 如FrameLoader.cpp:loadWithDocumentLoader
b namespace::class::func, 如WebCore::FrameLoader::load
何时用到GDB来调试
个人认为,并不是所有问题都立马上GDB来调试。因为Webkit的代码十分巨大逻辑也十分的复杂,所以直接用GDB,可能不是很直观,你无法在合理的位置设置断点,单步跟踪更是会让人崩溃,因为逻辑很复杂,有些函数不止一次被调用,再加上多态,使得你很难准确定位问题。我们调试的目的就是为了跟踪流程和准确的定位问题。所以通常的做法是先通过经验和Log把问题确定在一定范围之内,比如一个类之中,或者一个方法之中,然后再用GDB去仔细调试。所以,用到GDB调试的时候是:熟悉流程
可以确定一定的代码范围
调试的原理
这里并不是讲GDB是如何实现的,而是大致讲讲用GDB调试手机库的原理。因为库是运行在手机里的,而开发环境是在PC上的,所以并不是像PC上那样直接去调试,而是要用到GDB Server和GDB Client,以及编译出来的带有Symbol调试信息的库,才可以。这个调试所用的库(out/target/product/common/symbols/system/lib/libwebcore.so)有几百兆大小,而手机中运行的库(out/target/product/common/system/lib/libwebcore.so)才3M多。先是要把手机Browser进程关联到一个端口,再通过adb forward命令把手机的端口与PC的端口相映射,因为PC上的GDB与手机中的GDB Server就是通过这个端口来通信的。手机中运行gdbserver,它会与手机Browser进程通信,也就是与真正的库交互,而PC端运行GDB与带有调试信息的库交互,PC的GDB再通过端口与手机 中的GDB Server通信,这样我们就能够在PC上调试手机中的库了。
具体的设置步骤
首先,你需要一个已经编译好的Android源码及其编译输出的各种二进制文件,关于Android源码的获取和编译可以去Google。映射端口,在PC的Shell中运行
adb forward tcp:5039 tcp:5039
设置手机和GDB Server,打开手机Browser,进入adb shell,用ps命令找到Browser的pid,然后运行
gdbserver :5039 --attach pid
设置PC GDB,要运行源码下的GDB文件
mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gdb mydroid/out/target/product/generic/system/bin/app_process
之后,会进行GDB的提示符下面,先加载所要调试的库:
set solib-absolute-prefix mydroid/out/target/product/generic/symbols set solib-search-path mydroid/out/target/product/generic/symbols/system/lib
然后开始调试
target remote :5039
之后就可以用GDB命令去调试了。
每次调试,gdbserver都要重新设置,因为每次PID都会不一样,而gdb client端刚不需要重复。
为了简化流程,对于gdbserver的设置可以用Shell脚本来做,如下:
#!/bin/bash cd /work/mydroid ADB=./out/host/linux-x86/bin/adb $ADB forward tcp:5039 tcp:5039 $ADB shell am start -n com.android.browser/.BrowserActivity TMPFILE=tmp.txt $ADB shell ps > $TMPFILE #echo "tmp file is $TMPFILE"; while read user pid line; do #echo $line; if [[ $line == *browser* ]]; then echo "pid of browser is $pid"; browser_pid=$pid; fi done < $TMPFILE rm -f $TMPFILE; $ADB shell gdbserver :5039 --attach $browser_pid
可以把这段脚本保存为gdbserver.sh,把其中的路径更换为相应的源码路径即可。每次调试前先运行一次gdbserver.sh,手机端就设置好了。
client端的命令也很长,所以也可以用脚本:
/work/mydroid/prebuilt/linux-x86/toolchai http:// n/arm-eabi-4.4.3/bin/arm-eabi-gdb /work/mydroid/out/target/product/generic/system/bin/app_process
把它保存为gdbclient.sh,运行起来比较方便。
但对于GDB的Promt里面的设置库的过程则必须手动设置了,但所幸Client端不用每次都配置。
GDB常用命令
GDB会打开一个像Shell一样的Promt,输入命令,然后GDB会去执行。h或help 显示帮助信息
q或quit 退出GDB
r或run 运行程序
c或continue 继续运行至下一个断点
s或step 单步跟踪,会进入每一个函数调用
n或next 执行下一步,不会进行函数
ENTER(回车) 重复上一命令
b或break 设置断点
d或delete 删除断点,不带参数则删除所有断点
更详细参考:GDB Documentation
设置断点
可以用以下方法设置断点:b filename:lineno,如FrameLoader.cpp:1515
b filename:function, 如FrameLoader.cpp:loadWithDocumentLoader
b namespace::class::func, 如WebCore::FrameLoader::load
相关文章推荐
- 如何使用gdb调试android webkit内核代码
- 如何用GDB进行多线程调试
- 如何运用Gdb对ARM板上的程序进行远程调试
- Linux下的c如何进行GDB调试
- Window平台Grmon下如何使用gdb进行调试
- Xcode常用技巧(1)-使用Xcode进行代码分析及GDB调试
- 如何使用gdb调试android webkit内核代码
- 什么是 core dump ? 以及如何使用gdb对 core dumped 进行调试
- 如何使用gdb进行调试
- 如何用gdb进行汇编级的调试
- (转载)如何用gdb进行汇编级的调试
- 如何在Windows的命令行下进行程序编译和gdb调试
- 如何使用Eclipse和GDB对JNI代码进行调试(JAVA和C)
- 如何使用*.pdb与源代码进行Web程序的调试?
- 实用技巧:Gdbserver远程调试的具…
- iphone调试 gdb基本命令和技巧
- Android Studio如何用release签名进行debug调试
- android如何使用ndk-gdb调试native程序
- 说说如何使用unity Vs来进行断点调试
- 使用cocos创建的项目,如何进行源码调试?