Android gdb调试方法

来源:互联网 发布:压缩软件for mac 编辑:程序博客网 时间:2024/05/30 04:29

准备工作:

1、ubuntu系统安装adb工具;

2、ubuntu安装android开发源码;

3、设备上烧写userdebug rom(一般自带gdbserver,如果没有,需要编译一个进去);


调试步骤:

1) 启动要调试的程序

直接在调试设备上点击你要启动程序的图标,就可以让程序跑起来了。

光跑起来还不行,还需要知道这个程序在系统中当前的进程号是多少。可以在调试设备的adb shell上,通过下面的命令查到:

        ps | grep <PackageName>

其中,PackageName就是你要调试程序对应的包名,例如:


可以看到,对于本例来说,其进程号是8143。

2) 启动GDB服务器端

在调试Android设备上启动gdbserver,并让其attach到前一步运行的那个要调试的进程上去。命令如下:

        gdbserver :<PORT>--attach:<PID>

这个命令必须要用root用户来执行。命令中的PID参数就是前一步查看到的被调试进程号。由于要采用GDB远程调试模式,所以要让gdbserver打开一个端口,这里的PORT参数就是指定要打开哪个端口进行监听。

还是接着上面的例子,假设打开端口号是1234,并且从上一步查看到的进程号是8143,则结果是:


对了,还有一点需要注意的是,Android从4.4开始,强制打开了SELinux,其规则是不允许一个进程attach到一个非自己的子进程或兄弟进程上进行调试的,哪怕这个进程是以root用户启动的也不行。想要知道当前SELinux的工作模式,可以在adb shell下键入getenforce命令,例如:


这是在我运行Android 5.0系统的Google Nexus 5上运行的结果,可以看出,其已经默认打开了强制(Enforcing)模式。所以,要想调试成功,必须要关闭SELinux的强制模式,可以通过下面的命令来关闭:

        echo 0> /sys/fs/selinux/enforce

注意,这条命令必须用root用户来运行。下面看看运行后的结果:


可以看出,SELinux的模式已经从强制变成了允许(Permissive)。

3)建立PC和Android设备间的端口转发

前面的命令已经让gdbserver在Android设备上打开了一个端口,监听远端GDB的调试命令。不过,这个监听端口只在Android设备上有效,在PC端根本访问不到。这时候,需要用adb将Android设备上的端口转发到PC机上。请在PC上再打开一个控制台,并键入如下命令:

        adb forward tcp:<PC_PORT>tcp:<DEVICE_PORT>

这条命令的作用就是将发往PC机上端口为PC_PORT的TCP报文,发送到Android设备上DEVICE_PORT端口上。

假设还是想在PC上打开1234端口,映射到上一步在设备上打开的1234端口:


4)启动GDB客户端

GDB的客户端启动非常简单,只要在命令行下或者Cygwin下执行NDK中自带的gdb程序就可以了:



接下来,就要让这个在PC上的GDB客户端,连接上在Android设备上的GDB服务器了,命令如下:

        (gdb) target remote localhost:<PORT>

其中,参数PORT就是在第三步中,在PC上建立的转发端口。对于前面的例子,就是:


这时,在gdbserver端就会显示:


这就表示GDB客户端与服务端已经连接成功了。

设置android符号表

<gdb> set solib-absolute-prefix /home/wangyj/android_samsung_4.0/android_4.0.3_samsung_dev/out/target/product/smdkc110/symbols/
<gdb>set solib-search-path /home/wangyj/android_samsung_4.0/android_4.0.3_samsung_dev/out/target/product/smdkc110/symbols/system/lib


经过以上四个步骤之后,就可以在PC端使用常用的GDB命令,对Android设备上指定的程序进行调试了。


补充:使用gdbclient方便调试的方法,转自:http://blog.csdn.net/zero9988/article/details/51325872

二: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的源代码

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"># gdbclient now determines whether the user wants to debug a 32-bit or 64-bit  
  2. # executable, set up the approriate gdbserver, then invokes the proper host  
  3. # gdb.  
  4. function gdbclient()  
  5. {  
  6.    local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT)  
  7.    local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED)  
  8.    local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)  
  9.    local OUT_VENDOR_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED)  
  10.    local OUT_EXE_SYMBOLS=$(get_symbols_directory)  
  11.    local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS)  
  12.    local ARCH=$(get_build_var TARGET_ARCH)  
  13.    local GDB  
  14.    case "$ARCH" in  
  15.        arm) GDB=arm-linux-androideabi-gdb;;  
  16.        arm64) GDB=arm-linux-androideabi-gdb; GDB64=aarch64-linux-android-gdb;;  
  17.        mips|mips64) GDB=mips64el-linux-android-gdb;;  
  18.        x86) GDB=x86_64-linux-android-gdb;;  
  19.        x86_64) GDB=x86_64-linux-android-gdb;;  
  20.        *) echo "Unknown arch $ARCH"return 1;;  
  21.    esac  
  22.   
  23.    #参数1<span style="white-space:pre"> </span>  
  24.    if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then  
  25.        local EXE="$1"  
  26.        if [ "$EXE" ] ; then  
  27.            EXE=$1  
  28.            if [[ $EXE =~ ^[^/].* ]] ; then  
  29.                EXE="system/bin/"$EXE  
  30.            fi  
  31.        else  
  32.            EXE="app_process"  
  33.        fi  
  34.   
  35.        #参数2<span style="white-space:pre"> </span>  
  36.        local PORT="$2"  
  37.        if [ "$PORT" ] ; then  
  38.            PORT=$2  
  39.        else  
  40.            PORT=":5039"  
  41.        fi  
  42.   
  43.   
  44.        local PID="$3"  
  45.        if [ "$PID" ] ; then  
  46.            if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then  
  47.                PID=`pid $3`  
  48.                if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then  
  49.                    # that likely didn't work because of returning multiple processes  
  50.                    # try again, filtering by root processes (don't contain colon)  
  51.                    PID=`adb shell ps | \grep $3 | \grep -v ":" | awk '{print $2}'`  
  52.                    if [[ ! "$PID" =~ ^[0-9]+$ ]]  
  53.                    then  
  54.                        echo "Couldn't resolve '$3' to single PID"  
  55.                        return 1  
  56.                    else  
  57.                        echo ""  
  58.                        echo "WARNING: multiple processes matching '$3' observed, using root process"  
  59.                        echo ""  
  60.                    fi  
  61.                fi  
  62.            fi  
  63.            adb forward "tcp$PORT" "tcp$PORT"  
  64.            local USE64BIT="$(is64bit $PID)"  
  65.            adb shell gdbserver$USE64BIT $PORT --attach $PID &  
  66.            sleep 2  
  67.        else  
  68.                echo ""  
  69.                echo "If you haven't done so already, do this first on the device:"  
  70.                echo "    gdbserver $PORT /system/bin/$EXE"  
  71.                    echo " or"  
  72.                echo "    gdbserver $PORT --attach <PID>"  
  73.                echo ""  
  74.        fi  
  75.   
  76.   
  77.        OUT_SO_SYMBOLS=$OUT_SO_SYMBOLS$USE64BIT  
  78.        OUT_VENDOR_SO_SYMBOLS=$OUT_VENDOR_SO_SYMBOLS$USE64BIT  
  79.   
  80.   
  81.        echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS"  
  82.        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"  
  83.        echo >>"$OUT_ROOT/gdbclient.cmds" "source $ANDROID_BUILD_TOP/development/scripts/gdb/dalvik.gdb"  
  84.        echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT"  
  85.        # Enable special debugging for ART processes.  
  86.        if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then  
  87.           echo >> "$OUT_ROOT/gdbclient.cmds" "art-on"  
  88.        fi  
  89.        echo >>"$OUT_ROOT/gdbclient.cmds" ""  
  90.   
  91.   
  92.        local WHICH_GDB=  
  93.        # 64-bit exe found  
  94.        if [ "$USE64BIT" != "" ] ; then  
  95.            WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB64  
  96.        # 32-bit exe / 32-bit platform  
  97.        elif [ "$(get_build_var TARGET_2ND_ARCH)" = "" ]; then  
  98.            WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB  
  99.        # 32-bit exe / 64-bit platform  
  100.        else  
  101.            WHICH_GDB=$ANDROID_TOOLCHAIN_2ND_ARCH/$GDB  
  102.        fi  
  103.   
  104.   
  105.        gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE"  
  106.   else  
  107.        echo "Unable to determine build system output dir."  
  108.    fi  
  109.   
  110.   
  111. }  
  112. </span>  



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

source XXXX

XXXX:

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. define envset  
  2.   
  3.     target remote localhost:1234  
  4.   
  5.     file /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/bin/dex2oat  
  6.   
  7.     set solib-absolute-prefix /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbols  
  8.   
  9.     set solib-search-path /home/zero/aa/android-5.0.0_r3.0.1/out/target/product/generic/symbols/system/lib  
  10.     set breakpoint pending on  
  11. end  
  12.   
  13. define  argsSet  
  14.     set 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.oat  
  15.   
  16.   
  17. end  
  18.   
  19.   
  20.   
  21. define  bb1  
  22.     b frontend.cc:625 if method_idx==3  
  23.   
  24. end  




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

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #!/bin/sh  
  2.   
  3. CWD=`pwd`  
  4.   
  5.    
  6. export ANDROID_DATA="${CWD}/out/host/datadir/dalvik-cache/x86_64"  
  7. export ANDROID_ROOT="${CWD}/out/host/linux-x86"  
  8. BOOT_IMAGE="${CWD}/out/target/product/generic/system/framework/boot.art"  
  9. OUTPUT="${CWD}/out/oatfiles/arm"  
  10. #read x  
  11. #mkdir -p $OUTPUT  
  12. #mkdir -p $ANDROID_DATA  
  13.   
  14.    
  15. #exec gdb  
  16. exec gdb out/host/linux-x86/bin/dex2oat  


0 0
原创粉丝点击