1.           使用 gdbserver 调试
使用 JDWP 只能调试 java 层面的程序,如果想调试 C 层面的代码,需要使用 gdbserver 方式, gdbserver 的服务端和客户端都包含在 android 的源码中。
server 端是 out/target/product/xxxxxx/system/bin/gdbserver 。
client 端是 prebuild/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb ),不需另外安装。
(请看完本文再开始调试,尤其是“注意”部分)
本文依据张博的调试文档 , 

2.           调试前的准备:编译 DEBUG

1)          新建(或修改) ANDROID 源码根目录的 buildspec.mk ,加入以下内容
DEBUG_MODULE_lidvm:=true   虚拟机模块设为 debug
TARGET_CUSTOM_DEBUG_CFLAGS:=-O0 -mlong-calls
(请修改具体模块名,我调试的是虚拟机的 libdvm.so

2)         重编 dalvik 模块
$ make clean-libdvm
$ make dalvik snod

3)          重烧 system.img

3.           gdb server

1)          端口映射
$ adb forward tcp:5039 tcp:5039             把设备的 5039 端口映射到 PC 的 5039
设定之后用 netstat -na 命令可看到 PC 的 5039 端口已处于 listen 状态

2)          调试进程号为 2014 进程
$ adb shell
# ps 
找进程号
# gdbserver :5039 --attach 2014     指明 tcp 端口号和进程号
注意:用此方法只适用于对已运行的程序 debug (不能使用直接在 gdbserver 后跟程序名的方式运行)
此时 2014

4.           gdb client

1)          用命令行工具调试
$ $ANDROID_DIR/prebuilt/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb $ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process 注意可执行程序名必须是 app_process ,不是你所调试的程序名
(gdb) set solib-absolute-prefix $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/
(gdb) set solib-search-path $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/
以上路径为 GDB 默认库的搜索路径,即交叉编译器库路径,若不设定,则找不到符号表, ( 带符号表的库在 symbols/system/lib/* ,手机里 strip 后无符号表的库在 system/lib/* ,它们必须配套使用 )
(gdb) target remote :5039      指明 TCP 端口号
此时连接 gdb server ,可设断点调试,按 c

2)          用 eclipse

a)           安装 cdt ,使 eclipse 支持 c/c++

                                        i.               下载
http://www.eclipse.org/cdt/downloads.php 下载 cdt-master-4.0.0.zip

                                       ii.               解压
$ mkdir cdt; cd cdt; unzip ../cdt-master-4.0.0.zip

                                     iii.               将解压缩后的 features 、 plugins 两个文件夹的内容复制到 Eclipse 安装目录中
$ cp plugins/* ../../eclipse/plugins/
$ cp features/* ../../eclipse/features/

                                     iv.               重新开启 Eclipse 即可
$ eclipse -clean 在新建 project 中即可看到 c/c++

b)         

                                        i.               新建 C++ project ( 菜单 File->New->Project…)
不使用 default location ,把 Location

                                       ii.               取消自动编译选项 ( 菜单 Project->Build Automatically)

c)           配置 gdb 环境
配置 Debug Configurations( 菜单 Run->Debug Configurations…)

                                        i.               新建一个 C/C++ Local Application 的 debug configuration

                                       ii.               Main 选项卡中
指定 Project 为新建的 C++ 工程,
C/C++ Applications 为 :
$ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process

                                     iii.               Debugger 选项卡中
指定 Debugger 为 gdbserver Debugger ,
Main 子选项卡的 Gdb debuger 设为:
$ANDROID_DIR/prebuilt/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb 设为一个文件名,文件内容如下:
file $ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process
set solib-absolute-prefix $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/
set solib-search-path $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/
Connection 子选项卡:
Type 设为 TCP , Port number 设为 5039

                                     iv.               点击 Debug

d)         

                                        i.               找开某一C程序(菜单 ->Open file

                                       ii.               在程序中双击可设置断点,设置后断点出现在右上的 Breakpoints

                                     iii.               Debug 选项卡提供了工具调试 (suspend, resume 等 )

5.           加打印语句
如果需要在 C

1)          直接在代码中使用 printf ,此方法只能应用于从命令行启动程序的情况,运行时可以 adb shell

2)          使用程序中提供的重定项后的打印语句,并在 logcat 中看到它
例如在 libdvm.so 中使用 dvmFprintf(stderr, “xieyan log\n”);

6.          

1)          在找不到原因时,可以写一个在 android 可以运行的简单 c 语言程序用 gdbserver 调试,以简化问题, android 中 c 程序做法见:
http://www.top-e.org/jiaoshi/html/?157.html

2)          我的是在 arm-eabi-2.4.1 的编译器编出来的,你的可能不是,编译时用 make showcommands  确定你的系统使用的编译工具链,否则如果你 debug

3)          有时编译会引起源码目录的变化,请在左侧 Project explorer