在路上...

The development of life
我们一直都在努力,有您的支持,将走得更远...

站内搜索: Google

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
以前在安裝gdbserver的过程中出现了很多问题,导致导致实验没有成功。今天有搜到一些资料,并重新做了一遍,基本上算是成功了。虽然对当中的一些问题还是没搞很明白,但是还是记录下来,以备后用。

远程调试环境由宿主机GDB和目标机调试stub共同构成,两者通过串口或TCP连接。使用GDB标准程串行协议协同工作,实现对目标机上的系统内核和上 层应用的监控和调试功能。调试stub是嵌入式系统中的一段代码,作为宿主机GDB和目标机调试程序间的一个媒介而存在。(这段话的意思不是很明白,还望高手指教)
    就目前而言,嵌入式Linux系统中,主要有三种远程调试方法,分别适用于不同场合的调试工作:用ROM Monitor调试目标机程序、用KGDB调试系统内核和用gdbserver调试用户空间程序。这三种调试方法的区别主要在于,目标机远程调试stub 的存在形式的不同,而其设计思路和实现方法则是大致相同的。
    而我们最常用的是调试应用程序。就是采用gdb+gdbserver的方式进行调试。在很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程 序。采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采用gdb+gdbserver的方式进行调试。 gdbserver在目标系统中运行,GDB则在宿主机上运行。
   要进行GDB调试,目标系统必须包括gdbserver程序,宿主机也必须安装GDB程序。
一般Linux发行版中都有一个可以运行的GDB,但开发人员不能 直接使用该发行版中的GDB来做远程调试,而要获取GDB的源代码包,针对arm平台作一个简单配置,重新编译得到相应GDB。GDB的源代码包可以从 http: //ftp.cs.pu.edu.tw/linux/sourceware/gdb/releases/下载,我使用的版本为gdb-6.4。

一、编译安装gdb+gdbserver
下载到某个目 录,我下载到自己的用户目录:/home/may。
下载完后,进入/home/may目录,配置编译步骤如下:

#tar jxvf gdb-6.4-tar-bz2
#cd gdb-6.4
#./configure --target=arm-linux --prefix=/usr/local/arm-gdb -v
(参数说明:target是你的目标板,我的是arm-linux,prefix是你要安装的目标文件夹。)
#mak
#make install
#export PATH=$PATH:/usr/local/arm-gdb


接下来,建立gdbserver.进入gdbserver目录(gdb-6.4/gdb/gdbserver):
#./configure --target=arm-linux --host=arm-linux
#make CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc
(这一步要指定arm-linux-gcc的位置,修改Makefile 的CC为arm-linux-gcc
)


     

在这一步中出现问题:make CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc

问题:

    root@may:~/gdb-6.4/gdb/gdbserver# make CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc  /usr/local/arm/2.95.3/bin/arm-linux-gcc -c -Wall -g -O2    -I. -I. -I./../regformats -I./http://www.cnblogs.com/include -Ihttp://www.cnblogs.com/bfd -I./http://www.cnblogs.com/bfd remote-utils.c  remote-utils.c: In function `prepare_resume_reply':  remote-utils.c:686: parse error before `unsigned'  remote-utils.c:697: `gdb_id_from_wait' undeclared (first use in this function)  remote-utils.c:697: (Each undeclared identifier is reported only once  remote-utils.c:697: for each function it appears in.)  remote-utils.c:707: parse error before `void'  remote-utils.c:712: `mem_addr_ptr' undeclared (first use in this function)  remote-utils.c:712: `len_ptr' undeclared (first use in this function)  remote-utils.c:714: `ch' undeclared (first use in this function)  remote-utils.c:714: `from' undeclared (first use in this function)  remote-utils.c:714: `i' undeclared (first use in this function)  remote-utils.c:720: `j' undeclared (first use in this function) 
make: *** [remote-utils.o] Error 1
解决方法:在remote-utils.c文件中,直接将有unsigned的那行和前面的一行对换位置就行了!估计是C语言语法的问题!

 

 

这样做之后,再执行上述命令,就没有错误了。运行完上述命令,就会在gdbserver目录下生成gdbserver可执行文件,把它烧写到flash的根文件系统分区,或通过nfs mount的方式复制到你的开发板上就可以了。只要保证gdbserver能在开发板上运行就行。我是使用nfs mount的方式,在开发板上挂载宿主机的目录,并将生成的可执行文件gdbserver拷贝到宿主机上的共享目录中,以使其在目标板上可见。如:

mount -o nolock -t nfs 192.168.0.167:/mnt/nfs /mnt

192.168.0.167是宿主机的IP。当然,在使用这种方式时要启动nfs服务。

二、调试步骤

接下面就可以用gdb+gdbserver调试我们开发板上的程序了。在目标板上运行 gdbserver,其实就是在宿主机的minicom下。从上一步mount目录的过程中看出,我将应用程序(hello.c)和gdbserver都拷贝到宿主机的/mnt/nfs目录下了,从而在目标板的/mnt目录可以看到他们(当然你可以将他们再拷到目标板的其他位置),并对其进行操作。

   1、在宿主机上进行交叉编译,带参数-g加入调试信息。
    假设要调试的程序为hello.c。
    #arm-linux-gcc -g hello.c -o hello

   2、在目标板上开启gdbserver
       #gdbserver <host-ip>:2345 hello
        gdbserver开始监听2345端口(你也可以设其他的值),然后启动hello,你会看到“Process hello created:pid=88”

要进行gdb调试,首先要在目标系统上启动gdbserver服务。在gdbserver所在目录下输入命令:

(minicom下)
#cd /mnt
#./gdbserver 192.168.0.167:2345 hello

192.168.0.167为宿主机IP,在目标系统的2345端口开启了一个调试进程,hello为要调试的程序(主义编译时要加上-g选项)。

在这一步出现问题,./gdbserver: error while loading shared libraries: cannot open shared object...

板子的lib库中缺少一个文件libthread_db.so.1。根据网上查到的解决办法:将宿主机上的交叉编译工具中的lib库中的copy一个过来。于是乎我将/usr/local/arm/2.95.3/arm-linux/lib/libthread_db.so.1文件拷贝到目标板的/lib中后错误消失,并出现提示:

Process /tmp/hello created: pid=80
Listening on port 2345
(另一个终端下,在宿主机上)
#cd /
#export PATH=$PATH:/usr/local/arm-gdb/bin
#arm-linux-gdb hello
(gdb) target remote 192.168.0.100:2345
(192.168.0.100为开发板IP,端口号2345必须于gdbserver的一致,才能进行通信)

出现提示:

Remote debugging using 192.168.0.100:2345
[New thread 80]
[Switching to thread 80]
0x40002a90 in ??()
同时在minicom下提示:
Remote debugging from host
192.168.0.167(gdb)

连接成功,这时候就可以输入各种GDB命令如list、run、next、step、break等进行程序调试了。

注意:
建立链接后,就可以进行调试了。调试在Host端,跟gdb调试方法相同。注意的是要用“c”来执行命令,不能用“r”。因为程序已经在Target Board上面由gdbserver启动了。结果输出是在Target Board端,用超级终端查看。

仍然存在的问题:
远程调试一个程序时, pc端输入回馈如下:
(gdb) list
No symbol table is loaded.   Use the "file" command.
(gdb) step
Cannot find bounds of current function
(gdb) info program
Debugging a target over a serial line.
Program stopped at 0x14000.
It stopped with signal SIGTRAP, Trace/breakpoint trap.
(gdb) info thread
   1 thread 769   0x00014000 in ?? ()
warning: GDB can't find the start of the function at 0x14000.
(gdb) info stack
#0   0x00014000 in ?? ()

输入continue可以跑,
输入break的情况和下list是一样的.
也就是说,还是还不能正常对arm板上的应用程序进行调试。(但是在第二天,再次用带-g选项的交叉编译器编译了源程序后,可以成功进行远程调试了;不知道到底是为什么,嵌入式里面的很多东西我还不懂,但是在做的过程中,可真是痛苦阿!)


参考文档:http://blog.chinaunix.net/u/22630/showart_298299.html
                http://www.minigui.org/cgi-bin/lb5000/topic.cgi?forum=6&topic=6279
                http://szricky.blog.hexun.com/8886993_d.html
                http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!268.entry
posted on 2009-08-31 21:26  palam  阅读(2224)  评论(0编辑  收藏  举报