首页嵌入式 › 应用调试之使用gdb和gdbserver

应用调试之使用gdb和gdbserver

一、调试原理
这里的gdb调试是在pc机上对在开发板上运行的程序进行调试。具体来说的话,在pc机上要运行gdb,在开发板上运行dbserver。gdb调试的时候,pc机上的gdb向开发板上的gdbserver发出命令,而开发板上的gdbserver就会向应用程序发出信号,使应用程序停下来或者完成其他一些工作!由此我们知道,pc机上要运行gdb,开发板上要运行gdbserver!


二、安装gdb与gdbserver:需要gdb-7.4.tar.bz2

gdb:
2、解压:tar xvf gdb-7.4.tar.bz2
3、配置:cd gdb-7.4/

                ./configure –target=arm-linux
4、编译:make
5、安装:mkdir tmp
                make install prefix=$PWD/tmp
这里是安装到了我们当前目录的tmp里面
6、查看PC机上以前安装好的gdb版本:arm-linux-gdb -v
发现是7.4版本的,我们编译的正好也是7.4版本的哦!
7、拷贝:cp tmp/bin/arm-linux-gdb /bin/
以后我们如果想使用我们自己编译的gdb的话可以使用绝对路径:/bin/arm-linux-gdb
gdbserver
1、cd gdb/gdbserver/
2、配置: ./configure –target=arm-linux –host=arm-linux
3、编译: make CC=/usr/local/arm/3.4.5/bin/arm-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 <sys/ptrace.h>而没有:#include <linux/ptrace.h>,于是加上:#include <linux/ptrace.h>,再次编译:make CC=/usr/local/arm/3.4.5/bin/arm-linux-gcc,成功!
 
4、拷贝:将gdbserver拷贝到开发板的bin目录下
三、调试
1、编译要调试的应用程序:必须要加-g选项
测试程序如下(名字是:test_debug.c):
#include <stdio.h>
void C(int *p)
{
*p = 0x12;
}
 
void B(int *p)
{
C(p);
}
 
void A(int *p)
{
B(p);
}
 
void A2(int *p)
{
C(p);
}
 
int main(int argc, char **argv)
{
int a;
int *p = NULL;
 
A2(&a);  // A2 > C
printf(“a = 0x%x\n”, a);
 
A(p);    // A > B > C
return 0;
}
按如下编译它:arm-linux-gcc -g -o test_debug test_debug.c
2、运行时出现错误:
/mnt/code/28th_app_debug # ./test_debug
a = 0x12
Segmentation fault
下面就开始进行调试
3、在开发板上:gdbserver 192.168.183.127:2345 ./test_debug
打印出如下信息:
Process ./test_debug created; pid = 751
Listening on port 2345
其中192.168.183.127:本开发板的ip
       123:端口号,自己随便写的
       ./test_debug:要调试的程序
4、在PC上:/bin/arm-linux-gdb ./test-debug
                     target remote 192.168.183.127:2345
5、下面就可以正式调试了!我们先来说一下几个常用的命令
(1)l:列出所有源代码
(2)break main:在main处打断点
         break test_debug.c:11:在test_debug.c的11行打断点
(3)c:运行到断点处
(4)step:单步执行
(5)next:单步执行,但是step会进入函数里面,但是next不会
(6)print a:打印a这个变量的值
(6)quit:退出,输入此命令则开发板上的gdbserver也退出
更详细的命令,我们在下一节里面会进一步来讲讲的!
6、另一种调试方法
让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件
然后使用gdb根据core dump文件找到发生错误的地方
在ARM板上:
1. ulimit -c unlimited
2. 执行应用程序 : 程序出错时会在当前目录下生成名为core的文件
在PC上:
3、首先将core文件拷贝到pc机上
     然后:/bin/arm-linux-gdb ./test_debug ./core
打印出如下信息:
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-linux”.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>…
Reading symbols from /home/share/jz2440/test_debug…done.
[New LWP 748]
warning: /lib/libc.so.6': Shared library architecture unknown is not compatible with target architecture arm.
warning: /lib/ld-linux.so.2′: Shared library architecture unknown is not compatible with target architecture arm.
Core was generated by `./test_debug’.
Program terminated with signal 11, Segmentation fault.
#0  0x000084ac in C (p=0x0) at test_debug.c:6
6               *p = 0x12;
4、bt:可以显示调用关系
#0  0x000084ac in C (p=0x0) at test_debug.c:6
#1  0x000084d0 in B (p=0x0) at test_debug.c:12
#2  0x000084f0 in A (p=0x0) at test_debug.c:17
#3  0x00008554 in main (argc=1, argv=0xbeb32eb4) at test_debug.c:34

发表评论