打印

再议:嵌入式中自己编译gdb和gdbserver工具

[复制链接]
2682|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
db10|  楼主 | 2009-5-27 12:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
记得以前写过:“嵌入式中自己编译gdb和gdbserver工具”的帖子。
经过使用,发现一些由于开发环境的不同,编译的时候会出现一些问题,这个帖子是针对vmware+red hat9.0上编译通过,能跑的,经过实际9200,9261都是能用的,当然再9260没有试,身边没有可试的板子。
 发现在现在比较热的ubuntu下,编译时通不过。这都是自己尝试后看到的现象。

         嵌入式中自己编译gdb和gdbserver工具

目 录



一.序论                      2
二.开发环境说明             2
三.编译gdb和gdbserver工具    2
四.Gdbserver操作使用    5



一.序论
就目前而言,嵌入式Linux系统中,主要有三种远程调试方法,分别适用于不同场合的调试工作:
用ROMMonitor调试目标机程序、
用KGDB调试系统内核
用gdbserver调试用户空间程序。

  这三种调试方法的区别主要在于,目标机远程调试stub的存在形式的不同,而其设计思路和实现方法则是大致相同的。
而我们最常用的是调试应用程序。就是采用gdb+gdbserver的方式进行调试。在很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序。采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采用gdb+gdbserver的方式进行调试。Gdbserver在目标系统中运行,gdb则在宿主机上运行。

目标系统必须包括gdbserver程序,宿主机也必须安装gdb程序。一般linux发行版中都有一个可以运行的gdb,但开发人员不能直接使用该发行版中的gdb来做远程调试,而要获取gdb的源代码包,针对arm平台作一个简单配置
二.开发环境说明
嵌入式中自己编译gdb和gdbserver工具,由自己亲自编译通过并可以正确运行使用。所在环境是pc运行在red 9.0.硬件板子:at91rm9200,跑嵌入式linux-2.4.27.gcc为3.3.2,gdb和gdbservr源代码选用gdb-5.2.1(先后试过gdb6.0, gdb6.4, gdb6.6三个版本,这三个没有成功,具体以后有时间再研究),可以到ftp://ftp.gnu.org/gnu/gdb下载。.

三.编译gdb和gdbserver工具
   可以在根据下面一步一步做,也可以象我一样,做一个shell脚本文件,这样可以提高效率(可以在windows上先做好这个脚本,制作好后拷贝到pc的linux下,可能不能执行,要用:先执行dos2unix 脚本名 将dos格式转化成linux认识的文件,然后再执行chmod 777 脚本名。这样就可以直接执行这个脚本了)。
操作具体情况请看脚本里的注释,编译中,源代码中好像没有出现语法错误提示,如果有的话,也就是添加或取消包含.H文件。
#!/bin/sh
#编译gdb 
#download from http://cygwin.mirrors.pair.com/gdb/old-releases/
# tar -xjvf gdb-5.2.1.tar.bz2 
#文件的很多目录也许你还没有建立,跟我的电脑上不一致,则要自己建立起目录。
cd /usr/src/arm/gdb/gdb-5.2.1 
mkdir ../build-gdb 
cd  ../build-gdb
../gdb-5.2.1/configure --target=arm-linux --enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext 
#具体说明请看相关附录
make 
make install 
#export PATH=$PATH: /usr/src/arm/gdb/build-gdb/bin

#编译gdbserver gdb5.2.1版本
mkdir ../build-gdbserver 
cd ../build-gdbserver 
chmod +x ../gdb-5.2.1/gdb/gdbserver/configure 
CC=/usr/local/arm/3.3.2/bin/arm-linux-gcc ../gdb-5.2.1/gdb/gdbserver/configure arm-linux --without-included-regex --without-included-gettext 
#具体说明请看相关附录 
make 
cp -vf gdbreplay gdbserver  /nfsshare/gdb

注释:1.编译完主机上的gdb后,在我的电脑linux下:/usr/src/arm/gdb//build-gdb/bin 生成可执行的arm-linux-gdb和arm-linux-run(这个具体不知道干吗的)文件。
2.编译完在板子上跑的gdbserver后,在我的电脑linux下:/usr/src/arm/gdb/build-dbserver 生成板子上可执行的gdbreplay和gdbserver (这个具体不知道干吗的)文件。
上面:target是你的目标板,我的是arm-linux,prefix是你要安装的目标文件夹

具体说明附录:对应脚本里的两行编译配置:../gdb-5.2.1/configure --target=arm-linux --enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext 
还有:
CC=/usr/local/arm/3.3.2/bin/arm-linux-gcc ../gdb-5.2.1/gdb/gdbserver/configure arm-linux --without-included-regex --without-included-gettext 
上面两个配置,在我电脑如果书写成用\隔开的几行,这样不能运行,不知道为什么。我一直还没有搞明白,不过这是小问题。
上面的配置一定要加对,否则编译有问题,或者编译好后,使用时有问题,如运行不起来,或者运行时不能设置断点,只能全速跑。

整个编译过程如果碰到这些问题:
1.编译后,在板子上运行gdbserver后出现
[root@AT91RM9200DK /usr]$gdbserver: error in loading shared libraries: libthread
_db.so.1: cannot open shared object file: No such file or directory
出现这个问题,是跟上面的两个配置有关,如只是简单的配置了如网上流行的说法target host prefix,没有其他选项了。这样生成的gdbserver是要共享库的,目标文件在使用时要求有libthread_db.so.1共享库文件,可以尝试将gcc3.3.2(我自己使用的版本)交叉编译器下的这个文件拷贝到你的板子linux 下的/lib 或 /tm/lib,或/usr/lib(具体不是很明白,我试过拷贝在/lib),但是有这个文件后,会导致这个文件要调用libc.so.6这个文件,这个文件又需要libc-2.3.2.so ,这些文件更换后,最后更多文件依赖。原因是:我的根文件下面ramdisk解开后库文件的版本低,好像全是1.3.2版本的(在家没带板子),就是说libc-2.3.2.so,ld-2.3.2.so,还很多别的库文件都是1.0版本的。其实这些库只是版本低,在原来的ramdisk里都有,但是提示找不到。你上一步我也是跟综过的。
然而我用新的如gcc 3.3.2或3.4.1里面的库换掉后换掉后,如换成libc-2.3.2.so,ld-2.3.2.so,连根文件ramdisk启动不来,也就是说要改动init部分,也就意外重新做busybox部分,那工作量更大,然而我也做了busybox,发现新做的busybox做成ramdisk后,内核起不来,处在init过不去。
 所以如果文件版本不一致的话,busybox和ramdisk不是自己作的话,上面这种动态编译gdbserver然后再在板子上加共享库,那是很难成功的。
  上面这个原因,我没有搞定,如果有人知道原因,请提示我。谢谢!
2.为了解决问题,看了一篇老外的**,说可以在编译gdbserver时,改动gdbserver下面的Makefie.in或configure后的Makefile,里面的LDFLAGS改成 LDFLAGS= -static。
原始老外**:
[bgat@mars build-gdb] cd gdb/gdbserver
[bgat@mars build-gdb] make CC=arm-linux-gcc
[bgat@mars build-gdb] file gdbserver
./gdbserver: ELF 32-bit LSB executable, ARM, version 1 (ARM), dynamically linked (uses shared libs), not stripped
You probably don't want your gdbserver to use shared libraries, unless your target environment supports them (and you want to prove that they actually work!). To save some hair, you'll probably want to build a statically-linked gdbserver instead, so that you can debug even if shared libraries are broken. To do that, edit the Makefile in gdb/gdbserver, and modify LDFLAGS: 


LDFLAGS = -static
There may be other LDFLAGS flags already there, which you'll want to leave alone--- just add -static to the end of the list. In other cases, LDFLAGS may not exist at all; just add the above line somewhere near CFLAGS. 

Then, rebuild gdbserver: 


[bgat@mars build-gdb] make clean
[bgat@mars build-gdb] make CC=arm-linux-gcc
[bgat@mars build-gdb] file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, not stripped
Run arm-linux-strip on the executable, if you want to shrink it down: 


[bgat@mars build-gdb] arm-linux-strip gdbserver
[bgat@mars build-gdb] ls -l gdbserver
-rwxrwxr-x    1 bgat     bgat       249164 Aug  2 11:16 gdbserver

我这样编译gdbserver后,gdbserver终于可以运行了,但是让我失望的是,gdbserver调试时程序不能设置断点,跑一次就完了。提示:
warnning 
Cannot insert breakpoint 1.
  Error accessing memory address 0x8...
 上面这个原因,我没有搞定,如果有人知道原因,请提示我。谢谢!
3.尝试了快1个星期后,很多版本的gdb尝试过。最后就是使用了第三条说的方法编译的,通过了,gdbserver可以跑了,可以设置断点了,现在正常。

四.Gdbserver操作使用
  有关gdb和gdbserver调试操作使用说明,资料一大把,这里讲讲要注意的地方:
1.    在target machine输入
进入嵌入式板子gdbserver 目录下,执行hello程序,超级终端输入
gdbserver 59.69.74.87:2345 /目录/hello(注意hello程序编译时必须是带-g调试信息的)
 59.69.74.87主机IP,2345任意写一个。Hello一定要用arm-linux-gcc(我的板子)交叉编译,带-g编译。
2. 在target machin出现
Process hello created; pid = 68

3. 进入上面制作gdb时生成的arm -linux-gdb所在目录(也可以export),在PC机上输入
arm-linux-gdb hello (这个程序一定跟target machine程序保持一致,是交叉编译的)
(gdb) target remote 203.239.30.207:2345 (203.239.30.207为板子IP)
出现 Remote debugging using 59.69.75.186:2345
0x40002a00 in ?? ()

(gdb) c //相当于主机gdb的run命令 

此时目标机上出现
Remote debugging from host 59.69.74.87
hello,world

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

调试结束.
                                 次**献给热爱linux的所有人
                                 
作者:db10
                                             2007.12.11于深圳


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

2230

帖子

0

粉丝