标签:
学习android5.0以后的ART虚拟机,看了看源码,比较头疼,决定通过动态调试的方式去学习。
Art虚拟机有一个dex2oat的可执行程序。就想到了通过gdb和gdbserver来debug这个dex2oat。
记录一下调试方法:
gdb运行在本地系统(windows/linux)
gdbserver运行在android真机/模拟器上(adb shell ls /system/bin查看是否有gdbserver,如果没有,可以从源代码prebuild文件夹中获取,也可以从ndk的文件中获取)
Ps:gdb和gdbserver的版本要一致,不然会出错的
一:“
1,准备工作:
1-1,在prebuild文件夹中找到gdb和gdbserver的可执行文件(ndk中也有)
1-2,把gdbserver 通过adb shell push进system/bin
1-3,把dex2oat需要的hello.jar给push到/data/test/中
2,通过adb在android模拟器中通过gdbserver关联相关的进程或者启动相关进程
2-1,gdbserver关联相关的进程 : adb shell gdbserver :端口号1234--attach 进程pid
(进程pid可以通过adb shell,调试应用可以attach system_process(没有测试))
2-2,gdbserver启动相关的进程: adb shell gdbserver :端口号1234 dex2oat --dex-file=/data/test/hello.jar --oat-file=/data/test/hello.dex
3,端口映射:
在本地命令行:adb forward tcp:1234 tcp:1234
4,进行gdb所在目录,启动gdb
4-1,cd /home/zero/android-5.0.0_r3.0.1/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin
4-2,./arm-linux-androideabi-gdb
5,进入了GDB以后:
5-1,(gdb)target remote localhost:1234 (连接目标)
5-2,(gdb)file /home/zero/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/bin/dex2oat (找到可执行文件dex2oat,都是在android源码的这个bin目录下的)
5-3,(gdb)set solib-absolute-prefix /home/zero/android-5.0.0_r3.0.1/out/target/product/generic/symbols (不懂为什么要有这句)
5-4,(gdb)set solib-search-path /home/zero/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/lib (设置可函数路径??)
6,设置断点 ,开始执行
6-1,(gdb)b main
6-2,(gdb) c
1,在源码目录执行:
1-1,source build/envsetup.sh
1-2,lunch full-eng
2,类似上面的gdbserver的启动和adb forward的端口映射
3,启动gdbclient
gdbclient dex2oat :1234
4,设置断点,开始调试
envsetup.sh中关于gdbclient的源代码
<span style="font-size:18px;"># gdbclient now determines whether the user wants to debug a 32-bit or 64-bit # executable, set up the approriate gdbserver, then invokes the proper host # gdb. function gdbclient() { local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT) local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED) local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED) local OUT_VENDOR_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED) local OUT_EXE_SYMBOLS=$(get_symbols_directory) local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS) local ARCH=$(get_build_var TARGET_ARCH) local GDB case "$ARCH" in arm) GDB=arm-linux-androideabi-gdb;; arm64) GDB=arm-linux-androideabi-gdb; GDB64=aarch64-linux-android-gdb;; mips|mips64) GDB=mips64el-linux-android-gdb;; x86) GDB=x86_64-linux-android-gdb;; x86_64) GDB=x86_64-linux-android-gdb;; *) echo "Unknown arch $ARCH"; return 1;; esac #参数1<span style="white-space:pre"> </span> if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then local EXE="$1" if [ "$EXE" ] ; then EXE=$1 if [[ $EXE =~ ^[^/].* ]] ; then EXE="system/bin/"$EXE fi else EXE="app_process" fi #参数2<span style="white-space:pre"> </span> local PORT="$2" if [ "$PORT" ] ; then PORT=$2 else PORT=":5039" fi local PID="$3" if [ "$PID" ] ; then if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then PID=`pid $3` if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then # that likely didn't work because of returning multiple processes # try again, filtering by root processes (don't contain colon) PID=`adb shell ps | \grep $3 | \grep -v ":" | awk '{print $2}'` if [[ ! "$PID" =~ ^[0-9]+$ ]] then echo "Couldn't resolve '$3' to single PID" return 1 else echo "" echo "WARNING: multiple processes matching '$3' observed, using root process" echo "" fi fi fi adb forward "tcp$PORT" "tcp$PORT" local USE64BIT="$(is64bit $PID)" adb shell gdbserver$USE64BIT $PORT --attach $PID & sleep 2 else echo "" echo "If you haven't done so already, do this first on the device:" echo " gdbserver $PORT /system/bin/$EXE" echo " or" echo " gdbserver $PORT --attach <PID>" echo "" fi OUT_SO_SYMBOLS=$OUT_SO_SYMBOLS$USE64BIT OUT_VENDOR_SO_SYMBOLS=$OUT_VENDOR_SO_SYMBOLS$USE64BIT echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS" echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl" echo >>"$OUT_ROOT/gdbclient.cmds" "source $ANDROID_BUILD_TOP/development/scripts/gdb/dalvik.gdb" echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT" # Enable special debugging for ART processes. if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then echo >> "$OUT_ROOT/gdbclient.cmds" "art-on" fi echo >>"$OUT_ROOT/gdbclient.cmds" "" local WHICH_GDB= # 64-bit exe found if [ "$USE64BIT" != "" ] ; then WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB64 # 32-bit exe / 32-bit platform elif [ "$(get_build_var TARGET_2ND_ARCH)" = "" ]; then WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB # 32-bit exe / 64-bit platform else WHICH_GDB=$ANDROID_TOOLCHAIN_2ND_ARCH/$GDB fi gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE" else echo "Unable to determine build system output dir." fi } </span>
标签:
原文地址:http://blog.csdn.net/zero9988/article/details/51325872