1. 首先把要调试的程序上传到模拟器中。假定我们用 adb push hello /data/hello 将程序传到了模拟器的 /data 目录。注意确认 hello 有可执行权限。
2. 在模拟器上运行 gdbserver :<port> hello,启动调试。其中 port 是 gdbserver 在手机上监听的端口号,注意和后面我们用 gdb 连接的端口可能不是同一个。运行结果可能是:
# gdbserver :6789 hello Process hello created; pid = 277 Listening on port 6789
3. 为了让 gdb 能够连接到 gdbserver 监听的端口,我们需要让模拟器转发端口:
adb forward tcp:3456 tcp:6789
上面命令的意思是把外界连接模拟器3456端口的包转发到模拟器内部手机系统的6789端口,也就是前面我们让 gdbserver 监听的端口。
上述转发功能也可以用 telnet 连接到模拟器之后用 redir 命令实现,大家可以自己 Google,这里不再赘述。
执行上述命令后,我们用 netstat -an 应该就能看到一条:
Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 127.0.0.1.3456 *.* LISTEN
也就是说我们可以用 gdb 连接 3456 端口了。
4. 运行 NDK 中的 gdb(实际文件名是 arm-eabi-gdb):
:/Developer/android-ndk-r4b/build/prebuilt/darwin-x86/arm-eabi-4.4.0/bin/arm-eabi-gdb GNU gdb 6.6 Copyright (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=i386-apple-darwin8.11.1 --target=arm-elf-linux". (gdb)
运行后第一步自然是指定要调试的 target,我们要连接 gdbserver,所以命令是
(gdb) target remote localhost:3456 Remote debugging using localhost:3456 0xb0001000 in ?? () (gdb)
那么后面就可以开始调试了,这里用 c 命令就可以将 hello 程序运行起来。
小提示:如果是用 ndk-build 编译的程序,输出到 libs/armeabi/ 目录下的程序一般是已经被 strip 去掉了调试信息的,调试的时候可以先用 file 命令加载带调试信息的文件,一般在 obj/local/armeabi/ 目录下。例如,如果我们要调试的程序是 hello, 那么 libs/armeabi/hello 文件是没有调试信息的,有调试信息的文件是 obj/local/armeabi/hello.