应用调试之使用gdb和gdbserver

来源:互联网 发布:徒知徐州文言文翻译 编辑:程序博客网 时间:2024/05/15 05:07


一、调试原理

这里的gdb调试是在pc机上对在开发板上运行的程序进行调试。具体来说的话,在pc机上要运行gdb,在开发板上运行dbserver。gdb调试的时候,pc机上的gdb向开发板上的gdbserver发出命令而开发板上的gdbserver(是应用程序的父进程)就会向应用程序发出信号使应用程序停下来或者完成其他一些工作!由此我们知道,pc机上要运行gdb,开发板上要运行gdbserver
gdb程序需要1个带有调试信息的app文件,从这个文件里面可以得到一些调试信息,以后想打印a变量,gdb就会从带有调试信息的app文件确定a变量的地址,然后发命令给gdbserver,gdbserver再去访问app的内存空间。gdb是命令行的东西,GUI可以使用eclipe

二、安装gdb与gdbserver:需要 gdb-7.4.tar.bz2 
gdb:
1、下载: http://ftp.gnu.org/gnu/gdb/ 
2、解压:tar xjf gdb-7.4.tar.bz2
3、配置:cd gdb-7.4/
                ./configure --target=arm-linux
--build=编译该软件所使用的平台
  --host=该软件将运行的平台(默认是PC机)
  --target=该软件所处理的目标平台

4、编译:make
5、安装:mkdir tmp 
                make install prefix=$PWD/tmp
这里是安装到了我们当前目录的tmp里面
查看里面的内容

生成了一个名为arm--linux-gdb的程序。
查看Makefile  看默认的安装目录


6、查看PC机上以前安装好的gdb版本:arm-linux-gdb -v
发现是6.8版本的,我们编译的是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
--build=编译该软件所使用的平台
  --host=该软件将运行的平台(默认是PC机)
  --target=该软件所处理的目标平台
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指定的头文件的路径,头文件除

了去-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):
A函数调用-》B函数调用-》C函数-》给p赋值
A2函数调用-》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;
}
知道C函数发生错误,从上面知道调用关系有2条路径
-g选项是加调试信息,从而确定调用关系
按如下编译它:arm-linux-gcc -g -o test_debug test_debug.c

把生成的应用程序拷贝到网络文件系统上去
2、运行时出现错误:
 # ./test_debug
a = 0x12
Segmentation fault
下面就开始进行调试
//2345这个是端口,随便写,gdbserver再去访问app的内存空间
3、在开发板上:gdbserver 192.168.1.17:2345 ./test_debug
 
打印出如下信息:
Process ./test_debug created; pid = 751
Listening on port 2345
 
这是自己设置要调试的程序的IP和端口号
其中192.168.1.17:本开发板的ip
       2345:端口号,自己随便写的
       ./test_debug:要调试的程序
 gdb要链接到开发板端的应用程序
4、在PC上:/bin/arm-linux-gdb ./test-debug
                     target remote 192.168.1.17:2345
使用gdb命令来控制程序
 

再对A2(&a)打断点,在31行


5、下面就可以正式调试了!我们先来说一下几个常用的命令
(1)l:列出所有源代码
(2)break main:在main处打断点
         break test_debug.c:22:在test_debug.c的29行打断点
(3)c(continue):运行到断点处
(4)step:单步执行
(5)next:单步执行,但是step会进入函数里面,但是next不会
(6)print a:打印a这个变量的值
(6)quit:退出,输入此命令则开发板上的gdbserver也退出
更详细的命令,我们在下一节里面会进一步来讲讲的!
 
6、另一种调试方法
让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件
然后使用gdb根据core dump文件找到发生错误的地方
 
在ARM板上:
1. ulimit -c unlimited (在开发板上输入 ulimit -c 出现值为0时表示当程序出错时产生的core dump文件大小是0(不产生这个文件),unlimited 表示不限制大小
2. 执行应用程序 : 程序出错时会在当前目录下生成名为core的文件
 
在PC上:
3、首先将core文件(代表core dump)拷贝到pc机上

     然后:/bin/arm-linux-gdb ./test_debug ./core
test_debug文件里面含有调试信息

 
打印出如下信息:
 
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:可以显示调用关系
 main->A->B->C,在C 函数里的第6行出错了
#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

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一岁多头发少怎么办 孩子头发长得慢怎么办 小孩头发长得慢怎么办 头发出油不洗头怎么办 青少年掉头发很厉害怎么办 洗了冷水头头痛怎么办 头发烫染后干枯毛躁怎么办 扎不起来的短发怎么办 发际线掉头发怎么办偏方 头上脓包掉头发怎么办 小孩头发少又黄怎么办 发旋哪里头发少怎么办 每次洗头发都掉好多怎么办 10岁儿童掉头发怎么办 1岁半宝宝掉头发怎么办 头发掉发严重怎么办吃什么 掉了一块钱很气怎么办 头发软又少怎么办盘头 头发出油掉的厉害怎么办 头发很油又少怎么办 18岁头发发量少怎么办 头发少长的慢怎么办 额头大发际线高怎么办 前额两边的头发变少了怎么办 吃减肥药掉头发怎么办 牙长智齿吃饭疼怎么办 头发稀少容易掉发怎么办 大把掉发头发稀少怎么办 头发掉厉害洗生发灵更掉怎么办? 额头两侧和头顶头发少怎么办 额头前面头发少怎么办天生的 头两边的碎头发怎么办 30岁后头发少怎么办 生完孩子头发少怎么办 1岁宝宝头发少怎么办 头顶上的头发少怎么办呢 22岁头顶头发稀少怎么办 头发又稀又少怎么办 头顶的头发越来越少怎么办 四岁宝宝头发稀少怎么办 一岁宝宝头发稀少怎么办