今天又取得了一些进展,赶快写下来以免自己忘记。
自从Linux在我的板子上跑起来之后,我一直在想一个问题,怎么调试将来写的程序。其实我在Linux开发方面真得很外行,到了今天才知道GDB到底是干什么用的,呵呵。我相信很多人从Bootloader调试开始一直都使用LED啊,printf这样的方法来调试。我做毕设时,就是在MTDBLOCK里面划出一个USER分区,然后把编译好的程序放入文件系统映像,通过Bootloader用串口下到NAND里,然后mount上调试,实在很花时间。今天,白痴的我终于找到了一条捷径,已经不咳嗽了!
先介绍下DDD和GDB,GDB是一种用于调试Linux下程序的工具,它不仅能调试C/C++,还可以调试Pascal等很多其他语言。我们看个例子:假设有一个程序叫做test.c,要用GDB调试它,首先,编译的时候需要加上产生debug信息选项“-g”,如#arm-linux-gcctest.c -o test-g;然后,由于我们并不是开发本机程序,在目标机(arm)上需要用一个server启动这个含有调试信息的程序,当然,本机和目标机之间得有一定的数据共享方式(如nfs)和一定的通信方式(如以太网或串口);最后,在本机上启动一个GDB客户端,就可以登陆到目标机的server上调试程序了。GDB的原理网上也有很多文章说,可以搜索下,但是我是初学者,就不去看那些内容了。为了让大家更加明确GDB和DDD的区别,我们先看一个GDB的调试过程:
我通过以太网调试,本机IP地址192.168.2.31,目标机(arm开发板IP地址192.168.2.223),本机通过nfs共享开发目录lgraphics。
首先本机上编译:
lxz@lxzlinux:~/lgraphics>arm-linux-gcc lgraphics.c -o lg -g
切换到目标机:
[root@(none) lgraphics]# gdbserver192.168.2.31:2345 lg
Process lg created; pid = 402
Listening on port 2345
Process lg created; pid = 402
Listening on port 2345
切换到本机:
lxz@lxzlinux:~/lgraphics>arm-linux-gdb lg
GNU gdb 6.6
Copyright (C) 2006 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 certainconditions.
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=arm-linux"...
(gdb) target remote 192.168.2.223:2345 lg
Remote debugging using 192.168.2.223:2345 lg
0x40001290 in _start () from /lib/ld-linux.so.2
lxz@lxzlinux:~/lgraphics>arm-linux-gdb lg
GNU gdb 6.6
Copyright (C) 2006 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 certainconditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.
This GDB was configured as "--host=i686-pc-linux-gnu--target=arm-linux"...
(gdb) target remote 192.168.2.223:2345 lg
Remote debugging using 192.168.2.223:2345 lg
0x40001290 in _start () from /lib/ld-linux.so.2
此时,目标机上也会出现:
Remote debugging from host 192.168.2.31
在本机上输入:
(gdb) bmain
(设置断点到main函数)
Breakpoint 1 at 0x9c00: file lgraphics.c,line442.
(gdb)cont
(开始执行)
Continuing.
Breakpoint 1 at 0x9c00: file lgraphics.c,line442.
(gdb)cont
Continuing.
Breakpoint 1,main () atlgraphics.c:442
(遇到断点,并显示断点程序行)
442
int i,j,b = 0;
(gdb)step
(单步执行)
445
linitgraph("/dev/fb0");
(显示目前程序行)
442
(gdb)step
445
好了,看到这里,差不多就明白GDB是干什么的、怎么用了吧。我相信你会和我一样对GDB界面的不友好表示愤慨,想想Windows下的开发工具,哪一种调试的时候还是文本界面的。幸运的是,有一些勤快的人,帮我们写了很多GDB的图形化前端,我们更本不用像上面这样使用GDB。
开始说DDD。DDD是一种GDB的图形化前端,就是一种用图形界面帮你输入繁琐的GDB调试指令工具。当然,也有很多文章说DDD多么不足,用Insight来取代它之类的。我的Suse里恰好就有DDD,我也不管那么多了,先用了。看看用DDD的时候怎么调试:
一样本机上编译:
lxz@lxzlinux:~/lgraphics>arm-linux-gcc lgraphics.c -o lg -g
切换到目标机:
[root@(none) lgraphics]# gdbserver192.168.2.31:2345 lg
Process lg created; pid = 402
Listening on port 2345
Process lg created; pid = 402
Listening on port 2345
切换到本机:
lxz@lxzlinux:~/lgraphics> ddd-debugger arm-linux-gdb lg
lxz@lxzlinux:~/lgraphics> ddd-debugger arm-linux-gdb lg
然后就会启动DDD的图形界面,在窗口下方有一个文本输入框,这里就是ddd的基础gdb的所在,在这里输入targetremote 192.168.2.223:2345lg,提示信息和我们用GDB时候是一样的。不同的是,除了这句连接目标机的指令,其他指令都不用输入了,可以在图形化界面里找到,这我就不说了。另外,连接目标机的指令也可以用在DDD中设置,不用输入,可以查找其他介绍DDD使用的文章。下面是DDD的图形界面,工具栏下面的是watch,代码可以设置断点(红色点),可以看到单步位置(绿色箭头),右边是执行控制工具条,最下面是GDB的输入和输出显示。
看到这里,想我一样的菜鸟们一定发现了,原来Linux程序可以这么好调啊,简直和CE没有什么差别了,呵呵。下面介绍为了使用GDB+DDD所要做的东西。我不是从零开始建立的,具体的包依存关系我也不明白,只好假设你在安装Linux的时候已经安装了像GCC,DDD之类的工具。GDB的源代码包gdb-6.6.tar.bz2可以从
ftp://gcc.gnu.org上下载到,还有一个要求是你已经安装了交叉编译器arm-linux-gcc。
下载下来后:
# tar xvjf gdb-6.6.tar.bz2
# mkdir gdbbuild
# cd gdbbuild
# ../gdb-6.6/configure--target=arm-linux
--prefix=/home/lxz/lxzgdb
这里,--prefix参数是需要安装的目录,然后
# make
# make install
这样,arm-linux-gdb这个工具就在/home/lxz/lxzgdb/bin里头了,你可以把这个路径添加到PATH里面去
接下来建立gdbserver,在gdbbuild的上一级目录下
# mkdir gdbserverbuild
# cd gdbserverbuild
# CC=arm-linux-gcc ../gdb-6.6/gdb/gdbserver/configure--host=arm-linux
--prefix=/home/lxz/lxzgdbserver
一样,--prefix参数是需要安装的目录,然后
# make
# make install
# cd /home/lxz/lxzgdbserver/bin
# arm-linux-strip gdbserver
把这个gdbserver复制到你的开发板上,就OK了。
今天就写到这里。
=====================================================================================
SPLIT
=====================================================================================
=====================================================================================
SPLIT
=====================================================================================
ARM Linux 交叉调试工具及方法
一、交叉调试工具
1、主机 : arm-linux-gdb
2、 arm: gdbserver
在开发主机上运行 arm-linux-gdb 程序,可以通过串口或网口与驻留在 ARM 开发板上的 gdbserver
程序进行通信,完成 ARM 开发板上应用程序的调试和跟踪。
二、交叉调试工具的生成
1、下载 gdb 源码
要完成交叉调试需要以上两个工具,在 http://ftp.gnu.org/gnu/gdb/下载 gdb 源码,再进行配置和编
译即可获得以上两个工具软件。
gdb 源码的版本为: gdb-6.8
源码包名称: gdb-6.8a.tar.bz2
2、编译环境
开发主机系统: ubuntu11.10
开发主机 gcc 版本: 4.4.6
交叉编译器版本: 4.5.1
三、配置和编译
1、解压源码
首先进入 gdb-6.8a.tar.bz2 所在的目录,解压后会在当前目录生成新的源码目录: gdb-6.8,在 shell
下输入以下命令 (红色为命令 )。
bill@bill-zhang:~/Downloads$tar -xvf gdb-6.8a.tar.bz2
2、进入源码目录
进入 gdb-6.8 目录,命令如下:
bill@bill-zhang:~/Downloads$ cd gdb-6.8
bill@bill-zhang:~/Downloads/gdb-6.8$
创建目标文件目录,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$ mkdir output
3、编译 arm-linux-gdb
在源码目录下进行配置,配置完成后会在当前目录和 gdb 目录下生成 Makefile 文件,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$./configure --target=arm-linux --enable-shared
--prefix=/home/bill/Downloads/gdb-6.8/output/x86 --without-x --disable-gdbtk --without-
included-regex --without-include-gettext
编译,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$ make
编译过程中会出错,信息如下:
cc1: warnings being treated as errors
.././gdb/cli/cli-cmds.c: In function ‘pwd_command’:
.././gdb/cli/cli-cmds.c:323: error: ignoring return value of ‘getcwd’,declared with attribute
warn_unused_result
make[2]: *** [cli-cmds.o] Error 1
make[2]: Leaving directory `/home/bill/Downloads/gdb-6.8/gdb'
make[1]: *** [all-gdb] Error 2
make[1]: Leaving directory `/home/bill/Downloads/gdb-6.8'
make: *** [all] Error 2
经过对以上信息分析可知,编译时把告警按错误看待,所以编译失败。解决办法是修改 gdb-6.8/gdb
目录下的 Makefile 的第 145 行,即注释调” -Werror“即可
#WERROR_CFLAGS = -Werror
WERROR_CFLAGS =
安装,目标文件会安装在 /home/bill/Downloads/gdb-6.8/output/x86 目录下,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$ make install
4、编译 gdbserver
进入 gdbserver 目录,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$ make gdb/gdbserver
进行配置,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8$./configure --host=arm-linux
--prefix=/home/bill/Downloads/gdb-6.8/output/arm --without-include-regex --without-included-
gettext
编译,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8/gdb/gdbserver$make
安装,目标文件 gdbserver 会安装在 /home/bill/Downloads/gdb-6.8/output/arm 目录下,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8/gdb/gdbserver$make install
gdbserver 进行瘦身,命令如下:
bill@bill-zhang:~/Downloads/gdb-6.8/gdb/gdbserver$arm-linux-strip /home/bill/Downloads/gdb-
6.8/output/arm/gdbserver
四、测试
以调试测试例程为例:
源文件: test.c
编译目标可执行文件: gcc -g -o test test.c,注意一定要加上” -g“,否则不能进行调试。
1、目标板上操作
将生成的 test 文件和 gdbserver 下载到 ARM 开发板上,在开发板的 Shell 上输入:
#./gdbserver 192.168.1.100:2345 test
其中 192.168.1.100 为开发机的 IP 地址
2、开发机上操作
bill@bill-zhang:~/Downloads/gdb-6.8/gdb/output/x86$./arm-linux-gdb test
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux"...
(no debugging symbols found)
(gdb)target remote 192.168.1.5:2345
其中 192.168.1.5 为开发板的 IP 地址
连接上后开发板的串口上会出现以下打印:
Remote debuging from host 192.168.1.100
(gdb)