java 调试 gdb_android gdb 调试实例演示(有源代码篇)
android ndk代碼的調試本身還是有點麻煩的,因為本身google android的sdk
主要是面向廣大的java程序員的,所以后來發布的 ADT 集成開發環境對java的代碼調試
支持還是很好的,但是對于 ndk編寫的so代碼就沒有那么直觀的圖形界面的調試工具了。
相信將來google肯定要開發出來 調試c/c++代碼的圖形調試工具,但是目前大多數剛開始
用ndk編寫c或者c++代碼的程序員調試的時候一般還是打log,然后再根據log來進行分析。
這種方法雖然簡單,但是缺點也是很明顯的,很多詳細的信息不能調試,為了解決這個問題,
我寫了這篇 android gdb 調試本地so的實例演示,以供大家參考。
做任何事情都是有代價的,用log調試的方法簡單方便,用android gdb調試就需要記下一些
命令,并且做一些前期的準備工作了。
前期準備工作:
1 gdbserver 這個是需要放在android 手機里面的,一般放在 /system/bin/目錄即可。
注意:直接從android源碼編譯出來的 gdbserver 放到android 手機中運行一般會crash的
官方的說法是 bionic 庫不匹配導致,所以建議重新編譯一個gdbserver。具體如何
編譯 gdbserver 見我的另外一篇博客
http://sunzeduo.blog.51cto.com/2758509/1381552
2 對應版本的 androidgdb
比如我的gdbserver是shell@android:/ # gdbserver --version
GNU gdbserver (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
gdbserver is free software, covered by the GNU General Public License.
This gdbserver was configured as "arm-eabi-linux"
而使用的 android gdb應該是
root@ubuntu:~/Desktop# ./androidgdb --version
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
.
注意版本一致,而./androidgdb 需要你下載一個ndk里面有
我使用的在
/root/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb
這個路徑里面
3 會使用常用gdb命令,具體命令的介紹,見我的另外一篇博文
http://sunzeduo.blog.51cto.com/2758509/1387538
4 一個自己寫好的demo程序,這個我會放在附件中的,后面的調試都是以這個demo例子來進行的
這里先大概介紹一下 這個demo程序中 jni的文件,一共有三個文件,如下圖
target.c ? ? 是一個服務器代碼,隨著代碼啟動而啟動運行
socketclient.c ?是個客戶端代碼,給java層提供jni接口
socketback.c ? ?打醬油的不用管他
開始調試
前期準備的工作做好以后,可以開始調試了。
1 首先啟動要調試的程序,ps 獲取其進程號 (手機界面操作即可)
shell@android:/ # ps | busybox grep socketcomm
u0_a66 26175 125 494016 50792 ffffffff 40090a40 S com.example.socketcomm
root 27938 27933 860 336 c04fbc9c 4004a5f4 S /data/data/com.example.socketcomm/files/target
2 啟動gdbserver attach到目標進程 ?(手機shell中操作)
shell@android:/ # gdbserver remote:1234 --attach 26175
Attached; pid = 26175
Listening on port 1234
其中 remote:1234 表示映射成tcp的1234端口,這個時候重新打開一個 adb shell 在ps com.example.socketcomm
發現
shell@android:/ # ps | busybox grep example
u0_a66 26175 125 494016 50792 ffffffff 40090a40 t com.example.socketcomm
root 27938 27933 860 336 c04fbc9c 4004a5f4 S /data/data/com.example.socketcomm/files/target
進程狀態已經變成 t了,表示 attach已經成功了
3 啟動gdb 來進行調試 (pc環境中操作,我用的是ubuntu系統)
root@ubuntu:~/Desktop# adb forward tcp:1234 tcp:1234
首先端口映射,映射成 1234 端口號
root@ubuntu:~/Desktop# ./androidgdb
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
.
(gdb) target remote:1234
Remote debugging using :1234
0x40090a40 in ?? ()
(gdb)
這個時候已經進入 gdb了,當然現在還沒有加載symbols 所以gdb的很多調試還不能用 輸入 list
bt 這些命令還是不太直觀或者不能使用
這里使用 file命令將symbols文件加載進來。因為我們有源代碼,而本身android 源碼ndk編譯的時候
默認是加 -g選項的,沒有被 strip的so庫在
/root/android/temp/socketcomm/obj/local/armeabi
這個目錄下,而在libs下的so是被 strip過的版本(strip剝光,表示去掉了symbols符號表的版本)
如下圖:
(gdb) set solib-search-path /root/android/temp/socketcomm/obj/local/armeabi
這個命令將so 的路徑設置一下
設置完成以后
(gdb) list socketclient.c:97
92 LOGI("read data fail !");
93 return NULL;
94 }
95
96
97 buffer[recbytes]='\0';
98 LOGI("recv buff %s",buffer);
99
100 close(cfd);
發現已經有代碼顯示了
(gdb) b socketclient.c:97
Breakpoint 1 at 0x56dd7044: file jni/socketclient.c, line 97.
具體代碼看 socketclient.c 這兩行是接收到服務器打代碼,然后通過logcat 打印出來的
我們在這里設置斷點(gdb) b socketclient.c:97
Breakpoint 1 at 0x56dd7044: file jni/socketclient.c, line 97.
繼續執行(gdb) c
Continuing.
[New Thread 26648]
[Switching to Thread 26648]
Breakpoint 1, Java_com_example_socketcomm_JniSocketClient_cliensocket (
env=0x56d7e870, thiz=, jstr=)
at jni/socketclient.c:97
97 buffer[recbytes]='\0';
(gdb) print buffer
$1 = "server back buff 64", '\000'
(gdb) bt
#0 Java_com_example_socketcomm_JniSocketClient_cliensocket (env=0x56d7e870,
thiz=, jstr=) at jni/socketclient.c:97
#1 0x4074de34 in ?? ()
#2 0x4074de34 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
ok 在斷點處停止了,然后值也打出來了
更多調試技巧,需要看gdb的命令,demo程序見附件。
總結
以上是生活随笔為你收集整理的java 调试 gdb_android gdb 调试实例演示(有源代码篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 惰性_Python学习--
- 下一篇: @responseBody java_j