交叉编译gdb和gdbserver 1、下载gdb: 下载地址为: http://ftp.gnu.org/gnu/gdb/ 按照一般的想法,最新版本越好,因此下载7.2这个版本。当然,凡事无绝对。 我们以gdb-7.2.tar.bz2 这个文件为例。 2、解压缩: tarjxvfgdb−7.2.tar.bz2注:小技巧:Linux下一般压缩文件后缀为.tar.bz2和.tar.gz,它们解压命令有两三个选项是一致的:xf(v),前者再加上j选项,后者再加上z选项。3、进入该目录 cd gdb-7.2/ 4、配置 ./configure–target=arm−linux–program−prefix=arm−linux−–prefix=/usr/local/arm−gdb注:–target=arm−linux意思是说目标平台是运行于ARM体系结构的linux内核;–program−prefix=arm−linux−是指生成的可执行文件的前缀,比如arm−linux−gdb,–prefix是指生成的可执行文件安装在哪个目录,这个目录需要根据实际情况作选择。如果该目录不存在,会自动创建,当然,权限足够的话。5、编译、安装 make makeinstall幸运的话,会在–prefix指定的目录下生成三个子目录:bin、lib、share,我们需要的arm−linux−gdb就在其中的bin目录下。如果你不小心查看它的大小的话,会发觉它有14MB那么大!天呐!怎么会占这么多空间?没关系,我们可以为它瘦身。没错!就是使用strip命令! strip arm-linux-gdb -o arm-linux-gdb-stripped $ ls -lh 总计 33M
-rwxr-xr-x 1 latelee root 14M 12-14 16:16 arm-linux-gdb
-rwxr-xr-x 1 latelee root 3.1M 12-14 16:25 arm-linux-gdb-stripped
可以看到,strip后的文件大小只有3.1MB,瘦身效果明显!如果做广告的话,绝对有说服力。 这个文件就是我们以后远程调试时在主机上运行的交叉调试器了:在主机上执行,调试的却是另一种体系结构的代码。但是,光有主机的调试器还不够。还需要在目标板上运行一个叫gdbserver的东东。这个东东是怎么来的呢? 1、在刚才那个gdb解压后的目录:gdb-7.2,进入./gdb/gdbserver子目录 gdbserver 1、cd gdb/gdbserver/ 2、配置: ./configure –target=arm-hismall-linux –host=arm-hismall-linux –prefix=/mnt/hgfs/vmshare/gdbserver7.41/ (同样,target 和 host 为你的交叉编译器, prefix为安装的目录)
3、编译: make CC=make CC=arm-hismall-linux-gcc 出现错误: linux-arm-low.c: In function arm_stopped_by_watchpoint': linux-arm-low.c:642: error:PTRACE_GETSIGINFO’ undeclared (first use in this function) linux-arm-low.c:642: error: (Each undeclared identifier is reported only once linux-arm-low.c:642: error: for each function it appears in.)
解决方法:这里提示没有PTRACE_GETSIGINFO这个东西,这里搜索PTRACE_GETSIGINFO的路径为-I指定的头文件以及交叉 编译工
具链,我们不妨到交叉编译工具链里面去查找一下: cd /usr/local/arm/3.4.5/ grep “PTRACE_GETSIGINFO” * -nR 找到如下信息: arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202 arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202 distributed/arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202 distributed/arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202 说明PTRACE_GETSIGINFO是在交叉编译工具链:linux/ptrace.h文件里定义的,那么可能是头文件没有包含好吧! 我们到gdbserver下的linux-arm-low.c里面一看,可不是嘛,只有:#include
(gdb) bt
此时用bt看不到backtrace,也就是调用堆栈,原来GDB还不知道符号信息在哪里。我们告诉它一下:
(gdb) file ./a.out Reading symbols from ./a.out…done. Using host libthread_db library “/lib/tls/libthread_db.so.1”. (gdb) bt
此时backtrace出来了。
(gdb) l 8 sub(); 9 return 0; 10 } 11 12 static void sub(void) 13 { 14 int *p = NULL; 15 16 17 printf(“%d”, *p); (gdb)
对于GDBServer出现的问题 1. GDBServer调试时出现packet error 问题。 主要是虚拟机与目标机的网络连接要经过windows,数据包容易丢失。换到Linux系统下则恢复正常。