安卓* 系统级 Java*/C++ 代码调试(三)

2014-11-24 01:34:11 · 作者: · 浏览: 5
/lib/libcrypto.so.0.9.8
push: ./lib/service -> /lib/service
push: ./lib/libssl.so.0.9.8 -> /lib/libssl.so.0.9.8
push: ./lib/gdbserver -> /lib/gdbserver
push: ./lib/libncurses.so.5 -> /lib/libncurses.so.5
20 files pushed. 0 files skipped.
1770 KB/s (10526293 bytes in 5.805s)
4 KB/s (440 bytes in 0.099s)

请通过 gdb 远程连接系统服务器

已连接;pid = 309

监听端口 1234

使用 adb 将本地 TCP 端口 1234 转发至安卓设备:

$ adb forward tcp:1234 tcp:1234

要使用 Eclipse 工具,请转至 Debug 视图:

“调试按钮->Debug Configurations”,选择配置“system_process_1234”,然后点击“Debug”按钮。

\
图 23. 启动 C/C++ 调试工具

等待 gdb 连接至 gdbserver:

\
图 24. system_server C/C++ 调试工具

暂停任务、转至 Console(控制台)并输入命令“thread 1”和“go”,使任务退出无限循环。

thread 1
[Switching to thread 1 (Thread 309)]
#0 setgid () at bionic/libc/arch-x86/syscalls/setgid.S:10
10 pushl %ebx
go
system server in dead loop, trying to restore...done

设置断点,然后对代码进行调试。

4.2 调试安卓应用

与 system_process 类似,安卓应用也是通过 zygote 进行分解(fork)。 我们不能像使用主函数启动普通 C/C++ 程序那样来启动安卓应用。 要调试安卓应用,我们必须在开始的时候使其进入一个无限循环(如同 system_process 那样),这样我们能够尽早地将 gdbserver 连接到该应用。 然后,我们还需要为其创建一个 C/C++ 项目和调试配置。 方便起见,我们再次使用 C/C++ 项目 system_process 和调试配置 system_process_1234。

4.2.1 调试安卓应用

启动安卓设备,并使用 USB 线缆将其连接至主机。 执行下列脚本“start_app.sh”:

$ cd ~/android-sdk/android-debug-utility/target
$ ./start_app.sh
zygote:305
killall: gdbserver: no process killed
please launch the app

从安卓启动程序启动安卓应用,或者从 Eclipse 运行安卓应用。 屏幕上出现一条消息,告诉我们可以连接至应用。

$ ./start_app.sh
zygote:305
killall: gdbserver: no process killed
please launch the app
please connect to the app 1362 via gdb remote
Attached; pid = 1362
Listening on port 1234

要使用 Eclipse,请转至 Debug 视图。

“调试按钮->Debug Configurations”,选择配置“system_process_1234”,然后点击“Debug”按钮。

\图 25. 启动 C/C++ 调试工具

等待 gdb 连接至 gdbserver。

\
图 26. 安卓应用 C/C++ 调试工具

暂停任务、转至 Console(控制台)并输入命令“thread 1”和“go”:

[New Thread 1374]
[Switching to Thread 1362]
thread 1
[Switching to thread 1 (Thread 1362)]
#0 0xb75cb343 in android::IPCThreadState::clearCallingIdentity (this=0x983d580) at frameworks/base/libs/binder/IPCThreadState.cpp:375
375 {
go
android app in dead loop, trying to restore...done

设置断点,然后对代码进行调试。

4.3 调试安卓服务

在安卓初始化脚本 init.rc 中,下列原生服务随系统一起启动:

service mtpd /system/bin/mtpd
class main
socket mtpd stream 600 system system
user vpn
group vpn net_admin inet net_raw
disabled
oneshot

service keystore /system/bin/keystore /data/misc/keystore
class main
user keystore
group keystore
socket keystore stream 666

这些服务通常使用 C/C++ 来编写,其条目为 main()。 但是这些服务由初始化进程启动,如果我们手动运行这些服务,其表现可能有所不同。 要对服务进行调试,我们须使用脚本 start_service.sh。此外,我们还需要为其创建 C/C++ 项目和 C/C++ 调试配置。 方便起见,我们再次使用现有的 system_process 项目和调试配置。

4.3.1 调试安卓服务

使用: start_service.sh [ service name ]

在主机上键入:

$ cd ~/android-sdk/android-debug-utility/target
$ ./start_service.sh mtpd
init:1
killall: gdbserver: no process killed
killall: gdb: no process killed
5 KB/s (585 bytes in 0.099s)
please start the service: start mtpd

在目标设备上键入:

# start mtpd

然后屏幕上会显示一条消息,告诉你现在可以对该服务进行调试。

user@ubuntu:~/android-sdk/android-debug-utility/target$ ./start_service.sh mtpd
init:1
killall: gdbserver: no process killed
killall: gdb: no process killed
5 KB/s (585 bytes in 0.099s)
please start the service: start mtpd
please connect to the app 1561 via gdb remote

与其它安卓 Java 应用不同,服务是独立的 C/C++ 应用,不能使用与 zygote 相同的映像 app_process,因此我们需要修改默认配置,以指定服务二进制的位置。

\
图 27. 将安卓服务二进制设置为调试

然后我们使用配置 system_process_1234 来启动调试工具,并等待其连接至 gdbserver。

\
图 28.