使用gdbserver远程调试

转载:http://my.oschina.net/shelllife/blog/167914

gdbserver工具

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

[email protected]:~/work/system$ which arm-none-linux-gnueabi-gcc
/opt/arm-2009q3/bin/arm-none-linux-gnueabi-gcc
[email protected]:~/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
[email protected]:~/work/system$

如果找到了就直接跳到步骤4,没有的话就需要自行编译了。

编译gdbserver

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

编译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版本必须保证版本一致,否则会出现如下的问题:

[email protected]:~/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的版本是:

[email protected]:~/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,这样也可以保证两者的版本一致。

库问题

这里需要注意的是运行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处完成的。

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的环境变量:

[email protected]:~/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指定的路径进行搜索。

[email protected]:~$ 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)。

完。

时间: 2024-10-28 16:18:09

使用gdbserver远程调试的相关文章

gdbserver 远程调试问题:设置文件和so搜索路径

编写一个必然crash 的程序 #include <stdio.h> void crash(){ char *a=0; *a=0; } int main() { printf("hello world\n"); crash(); printf("after crash\n"); } 执行gdb 远程调试 gdbserver :1234 a.out 运行 gdb , 运行命令  target remote :1234 必须用 file 指定可执行文件,才能

gdbserver远程调试嵌入式linux应用程序方法

此处所讲的是基于gdb和gdbsever的远程调试方法.环境为:PC机:win7.虚拟机:10.04.下位机:飞嵌TE2440开发板. 嵌入式linux应用程序的开发一般都是在linux里面编写好代码,并用交叉编译器arm-linux-gcc编译好之后再下载到板子上运行.如果建立了远程调试(能够在PC机ubuntu中调试板子中的linux应用程序),这样对于开发程序是极其方便的. 以下是摘自网络上的一些方法.其中加入了自己所遇到的一些问题,并提出了解决方法. 1.首先建立nfs文件系统,让PC机

GDB + gdbserver 远程调试android native code

原文地址:GDB + gdbserver 远程调试android native code 作者:tq08g2z 以调试模拟器中的native library code为例. Host: ubuntuTarget: Android ICS 1.将gdbserver放入设备. 确保系统有arm-*-gdb,及存在设备端将要运行的gdbserver,gdbserver可以由google ndk中获取,在ndk的如下目录可以找到这个文件: 点击(此处)折叠或打开 android-ndk-r8/toolc

Windowns下远程调试Linux下程序(MinGW+GDB+SlickEdit+GDBServer)(有待完善)

前言: 本文思路来自嵌入式开发,Linux下远程调试开发板.废话不多说,开始吧!! Windown端: 一.下载和解压MiniGW, 从官网下载MiniGW,解压.(本例放在C:\) 二.下载和解压GDB:下载地址为:http://ftp.gnu.org/gnu/gdb/(本文以gdb-7.2为例,放在C:\) 三.在Windowns下编译GDB 运行C:\MinGW\msys\1.0\msys.bat $ cd c: $ cd gdb-7.2 $./configure --target=i68

Windows远程调试Linux上的C++程序:Eclipse+MingW+Samba+GDBserver

转自:http://www.heimizhou.com/windows-remote-debug-linux-c-plus-plus.html 最近有一个需求,就是需要在Windows上远程调试Linux上的C++程序,然后我就从网上搜集各种方法,但是发现很多方法中是先在Windows上编译程序,然后再从Linux上编译程序,最后进行远程调试,这种方法使我的调试不能进入源代码,后来经过尝试发现只需要在Linux上编译程序即可.下面从三个方面:需要安装的软件.安装与配置.配置远程调试,来介绍一下我

Windows下通过ARM目标板上的gdbserver进行远程调试的方法

因某种需要,要在Windows平台上进行程序开发,目标板是基于Micrel芯片(ARMv4t)做的,上面运行有Linux最小系统,只有最基本的命令,需要在Windows平台上交叉编译能在ARMv4t上运行的目标代码,并且还要能进行远程调试.基于这些需求,初步计划按以下步骤进行: 1.先在Windows平台上交叉编译一个简单的C语言程序,并上传到开发板上,能正常运行即可: 2.交叉编译gdbserver,并上传到开发板: 3.进行远程调试. 按上述计划,首先要找一个Windows环境下的交叉编译环

gdb 远程调试android进程 -转

什么是gdb 它是gnu组织开发的一个强大的unix程序调试工具,我们可以用它来调试Android上的C.C++代码. 它主要可以做4件事情: 随心所欲地启动你的程序. 设置断点,程序执行到断点处会停住.(断点可以是表达式) 程序被停住后,可以查看此时程序中发生的事. 动态改变程序的执行环境. GDB远程调试原理图 如图上所示,我们需要使用gdbserver依附到我们要调试的进程上,gdb通过adbd和手机上的gdbserver 进行socket通信. 远程调试实战 在手机上启动gdbserve

20150502 调试分析之 使用gdb远程调试ARM开发板

20150502 调试分析之 使用gdb远程调试ARM开发板 2015-05-02 Lover雪儿 今天我们要学习的是使用gdb和gdbserver来远程调试开发板程序. 下面是本人的一些具体步骤: 下载gdb-7.9.tar.gz地址: http://ftp.gnu.org/gnu/gdb/gdb-7.9.tar.gz 安装gdb tar -jxvf gdb-7.9.tar.bz2 ./configure -target=arm-none-linux-gnueabi --prefix=/hom

GDB远程调试(一)之DM8168下gdb远程调试环境的搭建

1.前言 gdb是较为流行和通用的linux环境调试工具,掌握它对于嵌入式开发工作来说非常必要,能够提高工作效率,快速发现和解决问题.最近有兴趣研究了下gdb使用,特总结如下以备以后查阅. 2.下载最新的gdb 下载地址:http://ftp.gnu.org/gnu/gdb/,选择目前最新的版本下载.我选择了gdb-7.7.tar.gz版本 3.编译gdb和gdbserver (1)解压到你的工作目录: [email protected]:~$ tar -xvf gdb-7.7.tar.gz (