使用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)。
相关文章
相关标签/搜索