使用GDB在ARM上进行开发调试

来源:互联网 发布:买隐形眼镜必知常识 编辑:程序博客网 时间:2024/05/31 13:16

一、安装GDB及GDB server 

1.1 GDB简介 

GDB调试环境由宿主机GDB和目标开发板的GDB server共同构成,两者通过串口或TCP连接。使用GDB标准串行协议协同工作,实现对目标机的系统内核和上层应用的监控和调试功能。 
GdbServer是GDB的一个组件,但通常不随发行版本的GDB一同发布,需要用户自行编译GDB的源代码包得到相应的GDB和GDBServer,可以从下载地址:http://ftp.gnu.org/gnu/gdb/,或者百度获取下载地址。 

1.2 安装GDB 

本例中目标板为Hi3520D,使用的GDB是GDB 7.2,宿主机为ubuntu10.4(vmware),本机开发环境为win7 x64。在获取源码gdb-7.2a.tar.gz(24MB)后,将其解压: 
1.tar zxvf gdb-7.2.tar.gz 
2.配置GDB,./configure –target=arm-Linux –enable-sim –prefix=/opt/arm-gdb(其中prefix为设置您所需要的安装目录) 
3.编译及安装,执行make,然后执行make install 
4.执行结束后,在/opt/arm-gdb/bin目录下可看到生成的应用程序。 
这里写图片描述 
5.将三个应用程序拷贝到/usr/local/bin。 

1.3 安装GDB server 

在编译安装GDB后,进入到目录gdbserver下,我的目录为/home/arm/gdb/gdb-7.2/gdb/gdbserver,在该目录下进行配置。在命令行里输入:./configure –target=arm-linux –host=arm-linux。接着,配置所采用的交叉编译器。我用的是Hi3520D,所用的交叉编译器为arm-hisiv100nptl-linux-gcc,因此我在命令行里输入 : 
make CC=/opt/hisi-linux-nptl/arm-hisiv100-linux/target/bin/arm-hisiv100nptl-linux-gcc 
注意,一定要写交叉编译器的绝对路径!在make的过程中可能会出错,提示: 
“linux-x86-low.c error: sys/reg.h: No such file or directory”。 
这时候,在#ifdef HAVE_SYS_REG_H这句前面加上一句: 
#undef HAVE_SYS_REG_H 
然后重新编译即可。编译完成后,在gdbserver目录下就会生成gdbserver和gdbreplay。,这两个文件就可以放在目标板上和开发编译的程序一起进行调试。而主机上可以采用编译出来的arm-linux-gdb作为主机端运行的调试。 
这里写图片描述

二、测试代码及应用程序生成 

为简单起见,我们就用一个十余行的C程序进行GDB调试演示。以下是C代码:

<code class="hljs perl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include<stdio.h></span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> a+b; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc ,char* argv[]) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> num1=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,num2=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span>; const <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> plusCount=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span>!=plusCount;++<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%dplus</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span>=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span>.\r\n"</span>,num1,num2,num1+num2); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%dplus</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span>=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span> byfunc.\r\n"</span>,num1,num2,add(num1,num2)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

在命令行里输入:arm-hisiv100nptl-linux-gcc test.c -g -o test 即可生成应用程序test。注意,编译时一定要加入-g参数,表示应用程序调试。 
这里写图片描述 

三、GDB+GDB server nfs调试方法 

进行调试前首先需要保证目标开发板与宿主机支持nfs。在宿主机上安装samba教程可自行百度获取,或者参考文章附录。本例中宿主机IP为218.192.171.55,目标板IP为218.192.171.72,开发环境(win7 x64)IP为218.192.171.78,宿主机的共享目录为/mnt/nfs。 
1.将gdbserver和test拷贝到/mnt/nfs,更改应用程序权限:chmod 777 gdbserver test。 
2.通过telnet或者minicom远程到目标板,挂载nfs: 
mount -t nfs -o nolock -o tcp 218.192.171.55:/mnt/nfs /nfsroot 
这里写图片描述 
3.进入/nfsroot目录,输入指令: 
./gdbserver 218.192.171.55:5000 test 
其中,218.192.171.55为宿主机IP,5000表示目标开发板的调试端口(一般任意大于1024的端口号均可)。 
这里写图片描述 
4.在宿主机命令行输入:arm-linux-gdb test,接着输入: 
target remote 218.192.171.72:5000 
连接成功后,出现如下提示: 
这里写图片描述 
5.在宿主机命令行输入:b add 设置断点为函数add,然后再输入’c’,执行程序。效果如下: 
这里写图片描述 
目标板端输出提示如下: 
这里写图片描述 
6.输入’c’,继续运行程序,直到结束。然后输入’q’退出gdb。效果图如下: 
这里写图片描述 
这里写图片描述 
注,本例仅进行简单测试,其它调试命令可参考附录。 

四、GDB+GDB server串口调试 

由于本人开发板未配有串口调试,故以下内容为搬运过来的。调试步骤如下: 
1.如果你用串口1调试test的话,你就要现在板子上运行命令:gdbserver hello /dev/ttyS0 (详情可以参考gdbserver目录下的readme文件)。 
2.在宿主机命令行输入: 
arm-linux-gdb test 
3.然后配置到串口,在宿主机命令行输入: 
set remotedevice /dev/ttyS0(这里设置串口1) 
set remote baud 9600 (这里设置串口波特率) 
set debug remote 1(可选) 
target remote /dev/ttyS0 
4.操作到这儿,gdb就应该和gdbserver联系上了。接下来的操作和nfs中的操作保持一致,就不再赘述。 

五、附录 

本博文参考了多家之言,并且肯定存在许多不足。如果哪里表述有问题,还烦请指正。另外,推荐以下网页,可进一步学习相关内容。

1.GDB在ARM上的调试实战 

http://blog.chinaunix.net/uid-2630593-id-2138581.html 

2.CentOS 6.3下Samba服务器的安装与配置 

http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.html 

3.GDB下载地址: 

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

4.GDB十分钟教程 

http://blog.csdn.net/liigo/article/details/582231

出处:http://blog.csdn.NET/kxc0720/article/details/45953563