原创 建立arm -linux远程调试环境

2010-9-24 19:58 3288 6 6 分类: MCU/ 嵌入式

                          建立arm -linux远程调试环境


 典型的调试工具搭建为:


Gdb+gdbserver+insight


若不需要图形界面,则使用GDB+gdbserver即可,当然习惯了windows下的图形界面,可以用insight。下面分别介绍使用:


 


一.GDB +GDBServer


1)总体介绍


GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。一般来说,GDB主要帮忙你完成下面四个方面的功能:    


 1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
     2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
     3、当程序被停住时,可以检查此时你的程序中所发生的事。
     4、动态的改变你程序的执行环境。从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现GDB这个调试工具的强大,大家可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。


 远程调试环境由宿主机GDB和目标机调试stub共同构成,两者通过串口或TCP连接。使用 GDB标准程串行协议协同工作,实现对目标机上的系统内核和上层应用的监控和调试功能。调试stub是嵌入式系统中的一段代码,作为宿主机GDB和目标机调试程序间的一个媒介而存在。
       就目前而言,嵌入式Linux系统中,主要有三种远程调试方法,分别适用于不同场合的调试工作:用ROM Monitor调试目标机程序、用KGDB调试系统内核和用gdbserver调试用户空间程序。这三种调试方法的区别主要在于,目标机远程调试stub 的存在形式的不同,而其设计思路和实现方法则是大致相同的。
而我们最常用的是调试应用程序。就是采用gdb+gdbserver的方式进行调试。在很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序。采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采用gdb+gdbserver的方式进行调试。


嵌入式Linux的GDB调试环境由Host和Target两部分组成,Host端使用arm-linux-gdb,Target Board端使用gdbserver。这样,应用程序在嵌入式目标系统上运行,而gdb调试在Host端,所以要采用远程调试(remote)的方法。进行GDB调试,目标系统必须包括gdbserver程序(在主机上正对硬件平台编译成功后下载到目标机上),宿主机也必须安装GDB 程序。一般Linux发行版中都有一个可以运行的GDB,但开发人员不能直接使用该发行版中的GDB来做远程调试,而要获取GDB的源代码包,针对arm 平台作一个简单配置,重新编译得到相应GDB。


 


2)安装arm-linux-gdb(宿主机) 以及 gdbserver(arm目标板)


下载gdb-6.6的源代码包
       http://www.gnu.org/software/gdb/download/

ftp://ftp.gnu.org/gnu/gdb


或者到chniaUnix 去下载


#tar jxvf gdb-6.6-tar-bz2
#cd gdb-6.6


#./configure--target=arm-linux-prefix=/usr/local/arm/gdb--with-solib-absolute-prefix=/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/target



(--target配置gdb的目标平台,--prefix配置安装路径,当然其他路径也可以, --with-solib-absolute-prefix 指定这个绝对路径很重要,否则到时候调试的时候会报一堆错误和警告,例如:


xxx is not at the expected address。


Error while mapping shared library sections。


因为对远程调试来说,你需要告诉 GDB 目标库所在的地方,这样它才能载入正确的拷贝--不然,它可能试图载入宿主机的库。


以上的路径 :/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/target 就是本人的目标机的lib所在的绝对路径。如果没有加入该路径的话,请参考文章附录中的法方。)


 


#make
#make install
(生成arm-linux-gdb,并存入/usr/local/arm /gdb/bin/)


gedit /root/.bashrc  添加:  export PATH=$PATH:/usr/local/arm/gdb/bin


(添加arm-linux-gdb到环境变量)


在终端任意路径:#arm-linux-gdb  检查是否安装成功。



进入gdb-6.6/gdb/gdbserver目录:


 


#./configure --target=arm-linux --host=arm-linux
(--target=arm-linux表示目标平台,--host表示主机端运行的是arm-linux-gdb)


#make CC=/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/usr/local/arm/2.95.3/bin/arm_v5t_le-gcc
(arm_v5t_le-gcc 是本人的交叉编译工具 ,因为gdbsever是在目标机上运行,当然要用交叉编译器编译啦。本人这里用的是绝对路径,当然也可以用相对路径但可能会出现make: arm_v5t_le-gcc: Command not found,也可以直接修改gdbserver目录下的Makefile文件中的环境变量CC)



没有错误的话就在gdbserver目录下生成gdbserver可执行文件。用arm-linux-strip命令处理一下gdbserver,将多余的符号信息删除,可让elf文件更精简,通常在应用程序的最后发布时使用。


最后把gdbserver可执行文件 下载到开发板。


 


3)gdb+gdbserver nfs调试流程
下面就可以用gdb+gdbserver调试我们开发板上的程序了。在目标板上运行 gdbserver,其实就是在宿主机的minicom下。我是在minicom下#mount 192.168.2.100:/ /tmp后做的(这里参数-o nolock可以不加,不加这一步执行得反而更快些),hello和gdbserver都是位于Linux根目录下,把主机根目录挂在到开发板的/tmp 目录下。
要进行gdb调试,首先要在目标系统上启动gdbserver服务。在gdbserver所在目录下输入命令:
(minicom下)
#cd /tmp
#./gdbserver 192.168.2.100:2345 hello
192.168.2.100为宿主机IP,在目标系统的2345端口(你也可以设其他可用的值,当然必须跟主机的gdb一致)开启了一个调试进程,hello为要调试的程序(必须-g加入调试信息)。
出现提示:
Process /tmp/hello created: pid=80
Listening on port 2345
(另一个终端下)
#cd /
#arm-linux-gdb hello
最后一行显示:This GDB was configured as “--host=i686-pc-linux-gnu,--target=arm-linux”...,如果不一致说明arm-linux-gdb有问题
说明此gdb在X86的Host上运行,但是调试目标是ARM代码。
(gdb) target remote 192.168.2.223:2345
(192.168.2.223为开发板IP)
出现提示:
Remote debugging using 192.168.2.223:2345
[New thread 80]
[Switching to thread 80]
0x40002a90 in ??()
同时在minicom下提示:
Remote debugging from host 192.168.2.100
(gdb)
注意:你的端口号必须与gdbserver开启的端口号一致,这样才能进行通信。建立链接后,就可以进行调试了。调试在Host端,跟gdb调试方法相同。注意的是要用“c”来执行命令,不能用“r”。因为程序已经在Target Board上面由gdbserver启动了。结果输出是在Target Board端,用超级终端查看。连接成功,这时候就可以输入各种GDB命令如list、run、next、step、break等进行程序调试了。

4)如何利用串口调试
如果你用串口1调试hello的话,你就要现在板子上运行命令:
gdbserver hello /dev/ttyS0 (详情可以参考gdbserver目录下的readme文件)
这时gdbserver就在等待gdb的应答信号了。
然后在pc机上运行命令:
xxx-linux-gdb hello
在xxx-linux-gdb里敲入入下命令:
set remotedevice /dev/ttyS0(这里设置串口1)
set remote baud 9600 (这里设置串口波特率)
set debug remote 1(可选)
target remote /dev/ttyS0
操作到这儿,gdb就应该和gdbserver联系上了。


 


 


 


二.insight的实现


 


1)首先下载insight6.8,里面已经包含gdb和gdbserver了


http://sourceware.org/insight/ 或者到chinaUnix去下载;


 


#./configure --target=arm-linux --enable-sim --prefix=/usr/local/arm/insight  --with-solib-absolute-prefix=/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/target


 


#make


#make install


 


insight6.8 在 make的时候可能会出错,提示说 eval.c中的subscript_array数组没有初始化;


解决办法:在源码包中,找到该文件,找到定义subscript_array处,在后面帮其初始化为0即可:subscript_array[XXX]={0};


成功安装后,因为arm-linux-insight依赖gdb,所以会自动编译出arm-linux-gdb。


接着修改环境变量。


在终端运行arm-linux-insight ,但运行失败(Fc12上面运行),提示大概说:


tk-init failed.....................................


查阅发现是一个相关的bug,在其他的版本上可能没关系,但在本人的Fc12上去不行。官方说在insight6.8-1中有修补,但是在http://sourceware.org/insight/ 上下载6.8-1总是失败。


 


2)编译于insight配对的gdbserver


在insight6.8的目录下有gdbserver,安照gdbsver的过程 安装即可。


 


 


附录:


没有./configure 指定 solib-absolute-prefix 遇到的错误,即解决过程参考


最好用前面提及的办法,在configure时 ,就指定solib-absolute-prefix 避免麻烦



调试过程如下:


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


(gdb) show solib-absolute-prefix


The current system root is "/opt/montavista/pro/devkit/arm/v5t_le/target".


上面这个路径即GDB默认的绝对搜索路径,即交叉编译器库路径


(gdb) show solib-search-path


The search path for loading non-absolute shared library symbol files is .


(gdb) set solib-search-path /work/install/bluetooth/lib


这个路径为若在solib-absolute-prefix指定的路径内没有搜索到库,则再继续尝试从该路径进行搜索。


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


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


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

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条