休息了將近半年後,貓開始上班了,又開始忙碌的生活。

 

最近正在玩Android,被指派了解如何利用GDB來對Android device來除錯。網路上可以找到一些資訊,不過實地操作起來,仍不免有狀況。尤其是如何用arm-eabi-gcc成功編譯程式,簡單的Hello world執行檔放上Andriod device後執行為什麼會segmentation fault,google找解答看得我眼花撩亂。

 

這裡特地放上我怎麼在Andriod上使用GDB,並且附上參考聯結。

 

 

1          ADB全稱Android Debug Bridge,是android sdk裡的工具,可以直接操作管理android模擬器或者真實的android設備。通過adb我們可以在Eclipse中方面通過DDMS來調試Android程序,說白了就是debug工具。

adb
的工作方式比較特殊採用監聽Socket TCP 5554等端口的方式讓IDEQemu通訊,默認情況下adbdaemon相關的網絡端口,所以當我們運行Eclipseadb進程就會自動運行。

ADB是採Client-Server架構,client端是使用者在操作的電腦,server端則是android deviceClient包含在SDK裡,device上不需安裝只需要在手機中打開選項Menu->Settings->Application->Development->USB debugging.

1.1         主要功能有

1.1.1   進行設備的shell   
adb shell就可以進入模擬器的shell環境中。也可以執行各種Linux的命令,其命令格式為:adb shell command
範例:
adb shell dir
就是列舉目錄,在Linux中根目錄為/而不是Windows上的C磁碟、D磁碟
adb shell dmesg
會列印出Linuxdebug訊息。

1.1.2   管理模擬器或設備的port映射(端口轉發?)
adb forward tcp:5555 tcp:1234 delault tcp 5555 轉發到1234

1.1.3   計算機和設備之間上傳/下載文件
使用adb push android123.txt /tmp/android123.txt命令可以把SDK\Tools下的android123.txt文件傳輸到模擬器的/tmp/文件夾中,需要注意的是/tmp/文件夾中內容會在Android模擬器重新啟動時清空。通過adb pull /tmp/android123.txt android123.txt命令就會把模擬器的tmp文件夾下android123.txt文件回傳到電腦SDK\Tools目錄下。

1.1.4   local apk軟體安裝置模擬器或android設備
adb install android123.apk,這樣名為android123的安裝包就會安裝到Android模擬器中,前提是android123.apk文件需要放到SDK\Tools目錄下。

1.2         Froyoadb位置在out/host/linux-x86/bin

1.2.1   Cd out/host/linux-x86/bin

1.2.2   ./adb shell (也可以直接設定
export PATH=$PATH:/home/builder/project/Froyo/out/host/linux-x86/bin )

1.2.2.1.1 可能會出現

*daemon not running. Starting it now *

*daemon started successfully *

Error:  device offline

1.2.2.1.2 執行

telnet localhost 5554

來進入emulator control console

(http://developer.android.com/guide/developing/tools/emulator.html#console)
telnet localhost 5554
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Android Console: type 'help' for a list of commands
OK

1.2.2.1.3 Exit 離開emulator control console後再執行adb shell可成功

1.3         參考資料

1.3.1   http://stenlyho.blogspot.com/2008/11/androidadb.html

1.3.2   http://blog.ben.idv.tw/2007/12/android-debug-bridge.html

1.3.3   http://www.cublog.cn/u3/97568/showart_1977014.html

1.3.4   http://developer.android.com/guide/developing/debug-tasks.html

 

2          GDB可以透過網路對target端的程式進行除錯,需要在target(device)執行gdbserver以及在host(local PC)執行控制gdbservergdbGdbserver source code較原來的gdb簡單,比較容易被portingtarget上。現在Gdbserver已經包含在android source code中,就在prebuilt目錄下。

 

3          Android Gdbserver其二進位檔就在prebuilt/android-arm/gdbserver/下,只需把gdbserver這個可執行檔放在模擬器上即可

3.1         adb push /home/builder/project/Froyo/prebuilt/android-arm/gdbserver/gdbserver /system/bin

3.2         如果告知 Read-only file system的話,執行adb remount,因為default是用read-only

3.3         Froyo來說,整包編譯完後,gdbserver就已經被放置在 out/target/product/generic/system/bin/,當emulator起來後,可以直接執行。

4          編譯測試程式

4.1         我們需要一個能夠在target端編譯的程式,因此要用cross-compilerAndroid預設的cross compiler位置可以從envsetup.mk 檔中找到如下:
ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin

4.2         Froyo是使用arm-eabi-4.4.0,如果cross-compiler選用錯誤,會造成檔案被放上emulator後無法執行或執行過程segmentation fault

4.3         在使用arm-eabi-gcc編譯前,要把toolchain加入path
export PATH=$PATH:/home/builder/project/Froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin

4.4         假設寫一個測試程式Hello.carm-eabi-gcc來編譯,要編譯過至少要有以下的flag
arm-eabi-gcc -g -o Hello Hello.c -Wl,-rpath-link=/home/builder/project/Froyo/out/target/product/generic/obj/lib,-dynamic-linker=/system/bin/linker -I/home/builder/project/Froyo/ndk/build/platforms/android-5/arch-arm/usr/include -L/home/builder/project/Froyo/out/target/product/generic/obj/lib -nostdlib /home/builder/project/Froyo/out/target/product/generic/obj/lib/crtbegin_dynamic.o –lc

4.5         如果沒有加上-dynamic-linker=/system/bin/linker,編譯完後的執行檔放到emulator上後執行,會出現”not found”的錯誤訊息。

4.6         如果沒有-I,則編譯時可能會出現”error: stdio.h: No such file or directory”

4.7         因為要加入debug informationgdb可以使用,compiler option上要加上-g。如果是編譯Android source,可以修改Android.mk,增加 ”LOCAL_CPPFLAGS+=-g” ”LOCAL_CFLAGS+=-g”。如果沒有-g,使用break 指令時會看到 ” No symbol table is loaded.  Use the "file" command.”

4.8         參考資料

4.8.1   編譯android原始碼到模擬器上執行 http://www.dotblogs.com.tw/neil/archive/2009/04/03/7838.aspx

4.8.2   Android 3D : use OpenGL ES 2.0 and NEON compiler options http://developer.qualcomm.com/blog/android-3d-use-opengl-es-20-and-neon-compiler-options

4.8.3   Android NDK http://developer.android.com/sdk/ndk/index.html

4.8.4   Hello World C program using Android Toolchain  http://android-tricks.blogspot.com/2009/02/hello-world-c-program-on-using-android.html

4.8.5   Dynamically linked "Hello, world!" for Android  http://honeypod.blogspot.com/2007/12/dynamically-linked-hello-world-for.html

4.8.6   [SOLVED] Need some help compiling  http://forum.xda-developers.com/archive/index.php/t-680200.html

4.8.7    

5          emulator上啟動gdbserver

5.1         啟動emulator

5.2         emulator上啟動gdbserver

5.2.1   targetadb client端輸入adb shell (參考1.2)

5.2.2   target端用gdbserver開啟要除錯的程式,並監聽某一個port,等待host端的gdb連線進來

5.2.2.1  gdbserver 10.0.2.2:1234 testprog

5.2.2.1.1 10.10.2.2host端的IPdefault 10.0.2.21234gdbserver監聽的port

5.2.2.1.2 如果啟動成功,會出現
Process /system/bin/libomstts created; pid = 1025
Listening on port 1234

5.2.2.1.3 如果testprog argument ,直接寫在test prog後面,例如:

#gdbserver 10.3.5.123:2345 testprog -o -v 123

5.2.2.2  如果要接觸一個已經存在的process,可以用

gdbserver 10.10.2.2:1234 –-attach your-desired-pid

5.3         為了讓gdb能連接到emulator gdbserver

5.3.1   targetadb client端輸入
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

5.3.2   5554emulator gdbserver的監聽port,以上命令是將所有到localhost:1234的數據轉發到emulator1234 port

5.3.3   如果沒有做redirhost在做 target remot時會出現” localhost:1234: Connection refused.”

6          最後在本機端(host)啟動gdb client

6.1         因為gdbserver只負責控制程式,但是關於程式碼內容和執行程式本身的資訊都還是由GDB負責,所以要先用GDB引入測試程式testprogArm-eabi-gdbAndroid Froyo toolchain裡的gdb

prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gdb testprog

或者是
export PATH=$PATH:/home/builder/project/Froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/
arm-eabi-gdb testprog

6.2         告訴gdb shard libraries的路徑,最好是絕對路徑

(gdb) set solib-search-path /home/builder/project/Froyo/out/target/product/generic/symbols/system/lib/

6.3         接著要連接到targettarget remote target_IP:gdbserver_port

6.4         (gdb)Target remote localhost:1234
Remote debugging using localhost:1234

6.5         接下來就可以直接使用gdb的指令了

在一般的gdb中,執行程式用 ”r” (run),不過在這裡,由於已經利用trget remote連上gdbserver執行程式了,所以使用 “c” (contunue)指令,可以得到

(gdb) c

Continuing.

Error while mapping shared library sections:

/system/bin/linker: No such file or directory.

[New Thread 311]

[Switching to Thread 311]

 

Breakpoint 1, main () at Hello.c:4

4              printf("\n Hello!!!!\n");

(gdb)

7          參考資料

7.1         Debugging with GDB http://source.android.com/porting/debugging_gdb.html

7.2         Debug Native C/C++ Application for Android http://www.cppblog.com/luonjtu/archive/2009/02/19/74310.html

7.3         How to use gdbserver on android http://jovechia.blogspot.com/2009/04/how-to-use-gdbserver-on-android.html

7.4         Lab 5 debugger Software emulator http://opencsl.openfoundry.org/Lab05_debugger.rst.html

7.5         Use gdbserver and gdb - remote debugging http://checko.blogspot.com/2006/05/use-gdbserver-and-gdb-remote-debugging.html

7.6         Debuggin Segmentation Faults and Pointer Problems http://www.cprogramming.com/debugging/segfaults.html

7.7         Gdbserver on android http://sunsetyang.eduol.cn/archives/2010/995588.html

7.8         GDB簡介
http://tetralet.luna.com.tw/index.php?op=ViewArticle&articleId=187&blogId=1

7.9         Android系統中調試動態連接庫so文件的步驟 http://blog.wjmjimmie.cn/2010/08/02/android%E7%B3%BB%E7%BB%9F%E4%B8%AD%E8%B0%83%E8%AF%95%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93so%E6%96%87%E4%BB%B6%E7%9A%84%E6%AD%A5%E9%AA%A4/

8          Note:

8.1         /home/builder/project/Froyo/是我Android source的根目錄,請更換成使用者自己跟目錄的路徑

arrow
arrow
    全站熱搜

    AppleAppleCat 發表在 痞客邦 留言(4) 人氣()