gdb和gdbserver调试android应用与可执行

来源:互联网 发布:java运行批处理 编辑:程序博客网 时间:2024/05/17 22:17

学习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 ps查看,调试应用可以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目录下的,一般的用户进程使用app_process)

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






二:gdbclient与gdb

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>



Ps,1,通过脚本方便调试:

source XXXX

XXXX:

define envsettarget remote localhost:1234file /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/bin/dex2oatset solib-absolute-prefix /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbolsset solib-search-path /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/libset breakpoint pending onenddefine  argsSetset args --runtime-arg -classpath --runtime-arg hello.jar --instruction-set=arm --runtime-arg -Xrelocate --host --boot-image=/home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/system/framework/boot.art --dex-file=hello.jar --oat-file=/home/zero/aa/android-5.0.0_r3.0.1/out/oatfiles/arm/hello.oatenddefine  bb1b frontend.cc:625 if method_idx==3end




3,通过shell脚本(.sh)定义环境变量,然后使用gdb调试:

#!/bin/shCWD=`pwd` export ANDROID_DATA="${CWD}/out/host/datadir/dalvik-cache/x86_64"export ANDROID_ROOT="${CWD}/out/host/linux-x86"BOOT_IMAGE="${CWD}/out/target/product/generic/system/framework/boot.art"OUTPUT="${CWD}/out/oatfiles/arm"#read x#mkdir -p $OUTPUT#mkdir -p $ANDROID_DATA #exec gdbexec gdb out/host/linux-x86/bin/dex2oat






0 0
原创粉丝点击