您的位置:首页 > 其它

使用gdbserver远程调试

2014-08-06 17:34 375 查看


gdbserver工具

先确定默认crosstool交叉编译器是否有自带gdbserver,如果有就不需要自行编译。一般都会带有对应的gdbserver工具,可以通过find命令查找确定:

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

到GNU官方FTP下载, 下载地址:

http://ftp.gnu.org/gnu/gdb/
编译GDB源码时只需要编译出gdbserver就可以了

?
这时会在/work/install/gdbserver目录下生成bin/gdbserver,将其拷贝到nfs文件系统

?
这里需要特别注意的是交叉编译的gdbserver和host调试用的gdb版本必须保证版本一致,否则会出现如下的问题:

?
产生这个问题时:编译gdbserver用的是gdb7.5,而arm-none-linux-gnueabi-gdb的版本是:

?
而我使用交叉编译工具链自带的gdbserver就不会有这个问题。除了使用自带的gdbserver外,另一种解决办法就是重新从gdb源码编译arm-none-linux-gnueabi-gdb,这样也可以保证两者的版本一致。


库问题

这里需要注意的是运行gdbserver还需要libthread_db库,若你自己做的文件系统内没有这个库的话需要从交叉编译器内拷一个过去。

?
注:若不知道缺少什么库可以根据运行时错误提示拷贝或者用先用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处完成的。
2)Host端GDB加载要调试的程序

这里要调试的程序得是交叉编译过的,并且加了-g参数。不过大部分编译程序默认就是加了-g参数的,这点可以从编译时的log看出。

?
3)连接到目标板调试服务

?
注:上面两行错误信息暂时不用管,原因还不清楚,但是暂时发现不影响使用。

连接成功后ARM板上的信息应该是这样的:

?
上面这行表示宿主机和开发板连接成功。现在我们就可以在Host端像调试本地程序一样调试ARM板上程序。不过,需要注意的是这里执行程序要用“c”,不能用“r”。因为程序已经在Target Board上面由gdbserver启动了。

调试过程如下:

?
若产生这个错误主要是由于该调试的应用程序使用到了额外的库,而这个库在gdb默认的搜索路径内没有

(相对与远程调试,gdb默认搜索的路径即为交叉编译器的库路径,下面我会介绍到)

因此,这里我们需要修改一下gdb默认的共享库搜索路径。

修改的办法是设置GDB的环境变量:

?
solib-absolute-prefix设置的是被搜索文件路径的前缀,一般设置为交叉编译工具链的库路径前缀,即不包括lib目录,lib目录的父目录,solib-search-path设置的是被搜索库文件的路径。solib-search-path可以有多个路径,中间按用:隔开, solib-absolute-prefix的值只能有一个。若在solib-absolute-prefix指定的路径内没有搜索到库,则再继续尝试从solib-search-path指定的路径进行搜索。

?
这点倒有点类似于系统默认库搜索路径与LD_LIBRARY_PATH的关系。

详细参考GDB手册中相关部分:

http://wiki.chinaunix.net/index.php/GDB_Manual_15_1

设置好solib-search-path后再运行程序:

?
运行成功

注:使用GDB调试时查看代码不是很方便。CLWEN使用VIM作为GDB前端界面,结合gdb的远程调试功能,动态的将程序当前运行的代码显示在VIM上,查看起来十分方便。其远程调试方法和GDB+GDB Server一样,但是多了一个GUI界面(VIM)。

原文链接: http://my.oschina.net/shelllife/blog/167914
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息