您的位置:首页 > 其它

应用调试之使用gdb和gdbserver

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

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

gdb:
1、下载: http://ftp.gnu.org/gnu/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(或者 gdbserver localhost: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 (在bin目录下,其实可以直接敲:arm-linux-gdb ./test_debug)

                     target remote 192.168.183.127:2345
 
5、下面就可以正式调试了!我们先来说一下几个常用的命令
(1)l:列出所有源代码

(2)break/b main:在main处打断点

         break test_debug.c:11:在test_debug.c的11行打断点

(3)c:运行到断点处

(4)step:单步执行

(5)next:单步执行,但是step会进入函数里面,但是next不会

(6)print a:打印a这个变量的值(打印16进制: p/x a)

(6)quit:退出,输入此命令则开发板上的gdbserver也退出

(7)bt: 显示调用堆栈

更详细的命令,我们在下一节里面会进一步来讲讲的!
 
6、另一种调试方法,根据core dump文件调试

让程序在开发板上直接运行,当它发生错误时,令它产生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.

…………

[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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gdb gdbserver