使用gdbserver遠程調試

gdbserver工具

先肯定默認crosstool交叉編譯器是否有自帶gdbserver,若是有就不須要自行編譯。通常都會帶有對應的gdbserver工具,能夠經過find命令查找肯定: php

hong@ubuntu:~/work/system$ which arm-none-linux-gnueabi-gcc
/opt/arm-2009q3/bin/arm-none-linux-gnueabi-gcc
hong@ubuntu:~/work/emrock/emrock/system$ find /opt/arm-2009q3 -name gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/thumb2/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/thumb2/usr/lib/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/armv4t/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/armv4t/usr/lib/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/usr/lib/bin/gdbserver
hong@ubuntu:~/work/system$

若是找到了就直接跳到步驟4,沒有的話就須要自行編譯了。 前端

編譯gdbserver linux

到GNU官方FTP下載, 下載地址: 
http://ftp.gnu.org/gnu/gdb/  shell

編譯GDB源碼時只須要編譯出gdbserver就能夠了
# cd gdb-6.7.1/gdb/gdbserver/ 
#./configure --host=arm-none-linux-gnueabi --prefix=/work/install/gdbserver 
#make 
#make install
這時會在/work/install/gdbserver目錄下生成bin/gdbserver,將其拷貝到nfs文件系統
#cd /work/install/gdbserver 
#cp bin/gdbserver /work/nfs/rootfs/bin

這裏須要特別注意的是交叉編譯的gdbserver和host調試用的gdb版本必須保證版本一致,不然會出現以下的問題: ubuntu

hong@ubuntu:~/work/$ arm-none-linux-gnueabi-gdb ./ipcr002_debug
(gdb) target remote 192.168.0.178:1234
Remote debugging using 192.168.0.178:1234
Malformed packet(b) (missing colon): ore:0;
Packet: 'T050b:00000000;0d:80bdc3be;0f:b0070040;thread:5c21;core:0;'
產生這個問題時:編譯gdbserver用的是gdb7.5,而arm-none-linux-gnueabi-gdb的版本是:
hong@ubuntu:~/work/system$ arm-none-linux-gnueabi-gdb --version
GNU gdb (Sourcery G++ Lite 2009q3-67) 6.8.50.20090630-cvs

而我使用交叉編譯工具鏈自帶的gdbserver就不會有這個問題。除了使用自帶的gdbserver外,另外一種解決辦法就是從新從gdb源碼編譯arm-none-linux-gnueabi-gdb,這樣也能夠保證二者的版本一致。 app

庫問題

這裏須要注意的是運行gdbserver還須要libthread_db庫,若你本身作的文件系統內沒有這個庫的話須要從交叉編譯器內拷一個過去。
# gdbserver -h (target) 
gdbserver: error while loading shared libraries: libthread_db.so.1: cannot open shared object file: No such file or directory 
# cp -avf lib/libthread_db* /work/nfs/rootfs_bluetooth_omap/lib/ 
`/lib/libthread_db-1.0.so' -> `/work/nfs/rootfs/lib/libthread_db-1.0.so' 
`/lib/libthread_db.so.1' -> `/work/nfs/rootfs/lib/libthread_db.so.1'
注:若不知道缺乏什麼庫能夠根據運行時錯誤提示拷貝或者用先用strace跟蹤一下:
#strace -f -F -o strace.log gdbserver -h
#vi strace.log  
發現以下字段:
872   writev(2, [{"gdbserver", 9}, {": ", 2}, {"error while loading shared libra"..., 36}, {": ", 2}, {"libthread_db.so.1", 17}, {": ", 2}, {"cannot open shared object file", 30}, {": ", 2}, {"No such file or directory", 25}, {"\n", 1}], 10) = 126
872   exit_group(127)                   = ?
得知缺乏libthread_db.so.1庫(紅色部分標出)。

調試過程

1)Target端創建遠程調試服務
# gdbserver 192.168.0.29:1234 obexftp (target)
Process obexftp created; pid = 858

Listening on port 1234 工具

其中IP地址爲用來遠程調試的上位機地址(如今直接被gdbserver忽略掉,因此能夠不寫),端口爲target TCP 監聽端口。目標程序不須要符號表,便可以是strip後的,這樣能夠節省存儲空間,全部的符號信息處理都是在Host端的gdb處完成的。 ui

2)Host端GDB加載要調試的程序
這裏要調試的程序得是交叉編譯過的,而且加了-g參數。不過大部分編譯程序默認就是加了-g參數的,這點能夠從編譯時的log看出。
# arm-linux-gdb obexftp  
GNU gdb 6.6.50.20070301 (MontaVista 6.6.50-2.0.1.0702865 2007-03-26) 
Copyright (C) 2007 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=i686-pc-linux-gnu --target=armv5tl-montavista-linux-gnueabi"...
3)鏈接到目標板調試服務
(gdb) target remote 192.168.0.178:1234 
Remote debugging using 192.168.0.178:1234 
Error while reading shared library symbols: 
Dwarf Error: Can't read DWARF data from '/opt/montavista/pro/devkit/arm/v5t_le/target/usr/lib/debug/lib/ld-2.5.90.so.debug'  
0x400007a0 in _start () from /opt/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux.so.3
注:上面兩行錯誤信息暫時不用管,緣由還不清楚,可是暫時發現不影響使用。
鏈接成功後ARM板上的信息應該是這樣的: 
# ./gdbserver 192.168.0.29:1234 obexftp  
Process obexftp  created; pid = 858
Remote debugging from host 192.168.0.29   # 這個ip地址是上位機的IP地址
上面這行表示宿主機和開發板鏈接成功。如今咱們就能夠在Host端像調試本地程序同樣調試ARM板上程序。不過,須要注意的是這裏執行程序要用「c」,不能用「r」。由於程序已經在Target Board上面由gdbserver啓動了。
調試過程以下:
(gdb) b main 
Breakpoint 1 at 0x9870: file obexftp.c, line 376. 
(gdb) info b 
Num Type           Disp Enb Address    What 
1   breakpoint     keep y   0x00009870 in main at obexftp.c:376 
(gdb) c 
Continuing. 
Error while mapping shared library sections: 
/work/install/bluetooth//lib/libobexftp.so.0: No such file or directory. 
Error while mapping shared library sections: 
/work/install/bluetooth//lib/libc.so.6: No such file or directory. 
Breakpoint 1, main (argc=1, argv=0xbed0dec4) at obexftp.c:384 
384             if (strstr(argv[0], "ls") != NULL)      most_recent_cmd = 'l'; 
(gdb)
若產生這個錯誤主要是因爲該調試的應用程序使用到了額外的庫,而這個庫在gdb默認的搜索路徑內沒有
(相對與遠程調試,gdb默認搜索的路徑即爲交叉編譯器的庫路徑,下面我會介紹到)
所以,這裏咱們須要修改一下gdb默認的共享庫搜索路徑。

修改的辦法是設置GDB的環境變量: spa

hong@ubuntu:~/work/system$ arm-none-linux-gnueabi-gdb -q ipcr002_debug_gdb
(gdb) show solib-absolute-prefix
The current system root is "".
(gdb) show solib-search-path
The search path for loading non-absolute shared library symbol files is .
(gdb) set solib-absolute-prefix /opt/arm-2009q3/arm-none-linux-gnueabi/libc
(gdb) set solib-search-path /tftpboot/ak_ipc
(gdb) show solib-absolute-prefix
The current system root is "/opt/arm-2009q3/arm-none-linux-gnueabi/libc".
(gdb) show solib-search-path
The search path for loading non-absolute shared library symbol files is /tftpboot/ak_ipc.

solib-absolute-prefix設置的是被搜索文件路徑的前綴,通常設置爲交叉編譯工具鏈的庫路徑前綴,即不包括lib目錄,lib目錄的父目錄,solib-search-path設置的是被搜索庫文件的路徑。solib-search-path能夠有多個路徑,中間按用:隔開, solib-absolute-prefix的值只能有一個。若在solib-absolute-prefix指定的路徑內沒有搜索到庫,則再繼續嘗試從solib-search-path指定的路徑進行搜索。 .net

hong@ubuntu:~$ ls -l /opt/arm-2009q3/arm-none-linux-gnueabi/libc
total 24
drwxr-xr-x  6 wenju wenju 4096 Oct 17  2009 armv4t
drwxr-xr-x  2 wenju wenju 4096 Oct 17  2009 etc
drwxr-xr-x  2 wenju wenju 4096 Oct 17  2009 lib  # 前綴爲父目錄,/lib/ld-linux.so .etc.
drwxr-xr-x  2 wenju wenju 4096 Oct 17  2009 sbin
drwxr-xr-x  6 wenju wenju 4096 Oct 17  2009 thumb2
drwxr-xr-x 10 wenju wenju 4096 Oct 17  2009 usr
這點倒有點相似於系統默認庫搜索路徑與LD_LIBRARY_PATH的關係。
詳細參考GDB手冊中相關部分:
http://wiki.chinaunix.net/index.php/GDB_Manual_15_1
設置好solib-search-path後再運行程序:
(gdb) set solib-search-path /work/install/bluetooth/lib/ 
(gdb) c 
Continuing. 
Error while reading shared library symbols: 
Dwarf Error: Can't read DWARF data from '/opt/montavista/pro/devkit/arm/v5t_le/target/usr/lib/debug/lib/ld-2.5.90.so.debug' 
Breakpoint 1, main (argc=1, argv=0xbe896eb4) at obexftp.c:384 
384             if (strstr(argv[0], "ls") != NULL)      most_recent_cmd = 'l'; 
(gdb) l 
379             char *output_file = NULL; 
380             char *move_src = NULL; 
381             /* char *inbox; */ 
382 
383             /* preset mode of operation depending on our name */ 
384             if (strstr(argv[0], "ls") != NULL)      most_recent_cmd = 'l'; 
385             if (strstr(argv[0], "get") != NULL)     most_recent_cmd = 'g'; 
386             if (strstr(argv[0], "put") != NULL)     most_recent_cmd = 'p'; 
387             if (strstr(argv[0], "rm") != NULL)      most_recent_cmd = 'k'; 
388 
(gdb)
運行成功

注:使用GDB調試時查看代碼不是很方便。CLWEN使用VIM做爲GDB前端界面,結合gdb的遠程調試功能,動態的將程序當前運行的代碼顯示在VIM上,查看起來十分方便。其遠程調試方法和GDB+GDB Server同樣,可是多了一個GUI界面(VIM)。
相關文章
相關標籤/搜索