1.下載Android Debugging Utilities
gdb and gdb-server (6.8)
2.啟動Android Emulator模擬器
$ emulator @1.5_R2
3.把gdb和調試檔案以及原始碼放到模擬器上
$ adb push gdb /data/bin
$ adb push helloworld /data/bin
以helloworld為例,原始碼要放在/data/bin/development/hello目錄下。
有的文章說將以上檔案放在/system/bin目錄下,但後果是一旦關掉模擬器,這些的檔案就消失了,下次又要重傳~所以推薦放在/data/bin目錄下。
4.啟動shell
$adb shell
如果提示檔案系統不可寫的話,執行:
#mount -o remount / /
5.因為Android檔案系統沒有/bin/sh, 所以我們拷貝一個bash檔案(點擊下載
)到/bin目錄下:
#mkdir /bin
$adb push bash /bin
或者設定SHELL的路徑:
#export SHELL=/system/bin/sh
6.進入/data/bin目錄,運行gdb,可以開始偵錯工具了
#cd /data/bin
#./gdb helloworld
-----------------------------------
調試Android上的c/c++程式一直是個難題,以前我經常
靠輸出log來解決問題,對於稍複雜一些的工程,這幾乎是個不可能完成的任務,尤其有些錯誤,在wincewindows下都沒事,只在android上
出現,就更難找了。後來看了些資料,知道可以用gdbserver來調試,今天決定必須把這個先弄清楚,不然以後幹活效率實在是太低了,找了很多網站,終
於成功了。這裡把整個過程整理一下,以備以後查閱。
1. 準備gdbserver。
android 1.0
代碼剛開放到時候,裡面並沒有帶gdbserver,有些強人就自己編譯了gdbserver來使用。不過現在好了,android的新源碼裡已經包含了
gdbserver,就在prebuilt目錄下。如果想在android 1.0裡使用,可以到如下地址下載:http://android.git.kernel.org/?p=platform/prebuilt.git;a=tree
。gdbserver的二進位檔案就在android-arm/gdbserver/gdbserver,我們只需要把gdbserver這個可執行檔放到模擬器上即可。
準備把它放在/system/bin,這樣它就在預設的PATH裡了。啟動模擬器後:
adb push gdbserver /system/bin
如果提示檔案系統不可寫的話,執行一下“adb remount”,因為預設是用唯讀模式掛載的。
2. 編譯器。
預設情況下,android的編譯系統在編譯器時已經使用了“-g”選項,即已經產生了調試資訊。但是在產生最終的檔案時,是經過strip的,去除了
所有到調試資訊。所以最終我們到偵錯目標要使用strip之前的檔案。用make showcommands查看詳細的命令資訊,下面是其中某次的輸出:
target Executable: libomstts (out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/LINKED/libomstts)
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-g++ -nostdlib
-Bdynamic -Wl,-T,build/core/armelf.x
-Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections
-Wl,-z,nocopyreloc -o
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/LINKED/libomstts
-Lout/target/product/generic/obj/lib
-Wl,-rpath-link=out/target/product/generic/obj/lib -llog -lcutils
-lutils -landroid_runtime -lnativehelper -lstdc++ -lz -lc -lstdc++ -lm
out/target/product/generic/obj/lib/crtbegin_dynamic.o
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/src/tts.o
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/src/TTSWrapper.o
out/target/product/generic/obj/lib/crtend_android.o
target Non-prelinked: libomstts (out/target/product/generic/symbols/system/bin/libomstts)
out/host/linux-x86/bin/acp -fpt
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/LINKED/libomstts
out/target/product/generic/symbols/system/bin/libomstts
target Strip: libomstts (out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/libomstts)
out/host/linux-x86/bin/soslim --strip --shady --quiet
out/target/product/generic/symbols/system/bin/libomstts --outfile
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/libomstts
Install: out/target/product/generic/system/bin/libomstts
out/host/linux-x86/bin/acp -fpt
out/target/product/generic/obj/EXECUTABLES/libomstts_intermediates/libomstts
out/target/product/generic/system/bin/libomstts
產生的可執行檔是libomstts,可以看到,初次連結的目標檔案是“out/target/product/generic/obj
/EXECUTABLES/libomstts_intermediates/LINKED/libomstts”,然後拷貝到“out/target
/product/generic/symbols/system/bin/libomstts”,strip後的檔案是“out/target
/product/generic/obj/EXECUTABLES/libomstts_intermediates/libomstts”和“out
/target/product/generic/system/bin/libomstts”。調試只能使用前兩個檔案。
把帶調試資訊到可執行檔放到模擬器上,我用到是“out/target/product/generic/symbols/system/bin/libomstts”:
adb push out/target/product/generic/symbols/system/bin/libomstts /system/bin
3. 啟動調試器
首先在模擬器上啟動gdbserver:
adb shell
進入模擬器的控制台後
gdbserver 10.0.2.2:1234 /system/bin/libomstts
10.0.2.2是模擬器的預設ip地址,讓gdbserver在模擬器上監聽1234連接埠。如果啟動成功會顯示以下資訊:
Process /system/bin/libomstts created; pid = 1025
Listening on port 1234
為來讓gdb能串連到模擬器上到gdbserver,必須進行資料轉寄:
telnet localhost 5554
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Android Console: type 'help' for a list of commands
OK
redir add tcp:1234:1234
OK
exit
上面的telnet localhost 5554,redir add
tcp:1234:1234,exit是自己輸入的命令,其他的是輸出資訊。5554是模擬器控制台的監聽連接埠,這些命令是將所有到
localhost:1234的資料轉寄到模擬器的1234連接埠。
最後在本機啟動gdb:
arm-eabi-gdb out/target/product/generic/symbols/system/bin/libomstts
arm-eabi-gdb是android內建的toolchain裡的,注意後面的可執行檔是strip之前的。
gdb啟動後,在gdb裡輸入命令串連gdbserver:
target remote localhost:1234
串連到gdbserver成功後,就可以使用所有的gdb調試命令啦
現在的這個gdbserver還不能調試動態連結程式庫,只能先編譯成可執行檔調試。