(于2010年8月5日更新,提示可用gdbtui调试,以及调试动态链接库有时遇到的调试问题,在第3.2节和第4节增加) 参考文章: 参考代码:(文件内容见最下面) 使用的平台: 注:编译Android略过,编译目标是默认的generic release版,若需要调试dalvikvm等系统自带程序,最好编译debug版本。 (选择device debug generic eng) 0. 准备工作 在Android源代码根目录执行 $ source build/envsetup.sh1. 使用没有被strip版本的执行文件HelloWorld和libtest.so $ make HelloWorld 没有被strip的版本所在位置是 将HelloWorld push到/data/bin/目录下,将libtest.so push到/system/lib/目录下 $ adb push ~/mydroid/android-1.6_r2/out/target/product/generic/symbols/system/bin/HelloWorld /data/bin/$ adb remount $ adb push ~/mydroid/android-1.6_r2/out/target/product/generic/symbols/system/lib/libtest.so /system/lib/ 2. 启动gdbserver 正常的话结果应该是:(不正常的话就自己查吧) Process /data/bin/HelloWorld created; pid = 206Listening on port 1234 不要忘记上面的pid,忘记了就ps呗 3. 启动arm-eabi-gdb进行调试连接
3.1 首先设置模拟器端口转发: $ adb forward tcp:1234 tcp:12343.2 启动arm-eabi-gdb:(android源代码prebuild目录下有相应文件,有多个版本,没查有什么区别,我用的是4.4) 启动后会显示: GNU gdb 6.6Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-elf-linux"... 3.3 首先执行set solib-×××的两个命令:(可选,只调试HelloWorld及其动态库的话不执行也无碍,最好是绝对路径,用自动扩展的写法可能不行) (gdb) set solib-absolute-prefix /home/j/mydroid/android-1.6_r2/out/target/product/generic/symbols/(gdb) set solib-search-path /home/j/mydroid/android-1.6_r2/out/target/product/generic/symbols/system/lib/ 3.4 连接gdbserver调试: (gdb) target remote :1234成功的话会显示: __dl__start () at bionic/linker/arch/arm/begin.S:3535 mov r0, sp Current language: auto; currently asm 如果没执行set solib-×××的两个命令会显示如下信息,但没关系 warning: Unable to find dynamic linker breakpoint function.GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. 0xb0000100 in ?? () 4. 进行gdb调试 (gdb) c 这是调试会停在HelloWorld.c的main函数处,提示信息如下: Continuing.Error while mapping shared library sections: libc.so: No such file or directory. Error while mapping shared library sections: libstdc++.so: No such file or directory. Error while mapping shared library sections: libm.so: No such file or directory. Error while mapping shared library sections: libtest.so: No such file or directory. Breakpoint 1, main () at /home/j/mydroid/android-1.6_r2/development/self/HelloWorld/HelloWorld.c:6 6 printf("main 1"); Current language: auto; currently c 最后几行表示调试正常,如果你编的debug版的Android,前几行会显示加载动态库成功,但也不能直接进入动态链接库进行调试的:)至少我这里不能。 这时你可以通过基本的gdb调试命令进行调试: (gdb) n (执行下一条)(gdb) b 10 (在第10行设断点) (gdb) list (显示源代码信息) (gdb) c (继续至下一断点或结束) (注:其实我不了解gdb调试,还是google一下比较好) 若你在func()处执行s命令进入func()函数体,就会提示错误,也无法进行正常调试了,如何调,请继续下一节— 5. 加载动态库so文件进行调试 5.1 查看动态链接库加载的内存地址 $ adb shell cat /proc/206/maps结果中会有如下几行: 00009000-0000a000 rwxp 00001000 1f:01 712 /data/bin/HelloWorld40000000-40008000 r-xs 00000000 00:07 186 /dev/ashmem/system_properties (deleted) 80000000-80001000 r-xp 00000000 1f:00 713 /system/lib/libtest.so 80001000-80002000 rwxp 00001000 1f:00 713 /system/lib/libtest.so afc00000-afc21000 r-xp 00000000 1f:00 478 /system/lib/libm.so 记录下80000000这个地址。 5.2 查看动态链接库libtest.so中text段的偏移地址 $ ./prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-objdump -h ~/mydroid/android-1.6_r2/out/target/product/generic/symbols/system/lib/libtest.so |grep .text结果显示为: 5 .text 00000034 00000344 00000344 00000344 2**2记录00000344这个地址。 5.3 在gdb中加载动态链接库 5.4 进入动态链接库进行调试 5.4.1 通过s命令进入 (gdb) c 当调试停在HelloWorld.c的第十行时,执行s命令: Breakpoint 2, main ()at /home/j/mydroid/android-1.6_r2/development/self/HelloWorld/HelloWorld.c:10 10 func();(gdb) s 这时就会显示libtest.c的代码,执行list命令进行查看: func () at /home/j/mydroid/android-1.6_r2/development/self/libtest/libtest.c:33 void func(){(gdb) list1 #include "stdio.h" 2 #include "libtest.h" 3 void func(){ 4 printf("libtest 1"); 5 printf("Hello, This is a function in libtest!"); 6 printf("libtest 2"); 7 } 5.4.2 通过设置断点进入 在libtest.c中设置断点: (gdb) b libtest.c:5Breakpoint 3 at 0x80000352: file /home/j/mydroid/android-1.6_r2/development/self/libtest/libtest.c, line 5.(gdb) cContinuing.Breakpoint 3, func () at /home/j/mydroid/android-1.6_r2/development/self/libtest/libtest.c:5 5 printf("Hello, This is a function in libtes t!”); 如此,就可以进行了动态链接库的调试了。 注意:我在使用时,在进入到动态链接库中调试时无法使用n命令,可以使用c finish b等命令。 下面这两个页面有改进的调试: 参考文章: 附文件内容: ./HelloWorld/Android.mk
./HelloWorld/HelloWorld.c
./libtest/Android.mk
./libtest/libtest.h
./libtest/libtest.c
|