热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux应用调试技术之GDB和GDBServer(讲的清楚)

1、调试原理GDB调试是应用程序在开发板上运行,然后在PC机上对开发板上得应用程序进行调试,PC机运行GDB,开发板上运行GDBServe

 


1、调试原理

  GDB调试是应用程序在开发板上运行,然后在PC机上对开发板上得应用程序进行调试,PC机运行GDB,开发板上运行GDBServer。在应用程序调试的时候,pc机上的gdb向开发板上的GDBServer发出命令,而开发板上的gdbserver就会向应用程序发出信号,使应用程序停下来或者完成其他一些工作。

 

2、安装GDB和GDBServer(gdb-7.4.tar.bz2 )

  2.1、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

    6、拷贝:cp tmp/bin/arm-linux-gdb  /bin/

    7、查看版本 /bin/arm-linux-gdb -v (使用绝对路径使用gdb)

  2.2、GDBServer

    1、cd gdb/gdbserver/

    2、配置: ./configure --target=arm-linux --host=arm-linux

    3、编译: make CC=arm-linux-gcc

 

  2.3、编译GDBServer的时候会出现以下错误

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宏,导致编译错误。我们到交叉编译链去搜索一下,我们交叉编译地址为 /work/tools/gcc-3.4.5-glibc-2.3.6

# cd /work/tools/gcc-3.4.5-glibc-2.3.6
# 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宏为0x4202,头文件为include中。

  有两种解决办法,可任选其一:

  ① 在linux-arm-low.c中直接添加宏 #define PTRACE_GETSIGINFO 0x4202

  ② 在linux-arm-low.c中将#include 更改为 #include

  再次编译,编译通过。

  2.4、将gdbserver拷贝到开发板的bin目录下

#cp gdbserver /work/nfs_root/first_fs/bin

 


 3、调试

  3.1、在编译要进行调试的应用程序 加上 -g

   测试程序如下(test_debug.c)

  

 

#include 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 > Cprintf("a = 0x%x\n", a);A(p); // A > B > Creturn 0;
}

 

   编译:

#arm-linux-gcc -g -o test_debug test_debug.c

3.2、在开发板上:

  打印出如下信息:

#gdbserver 192.168.1.10:123 ./test_debug
Process ./test_debug created; pid = 751
Listening on port 2345

 

  注释:192.168.1.10:本开发板的ip

          123:端口号,自己随便写的

          ./test_debug:要调试的程序

3.3、在PC上输入:

    /bin/arm-linux-gdb ./test-debugtarget remote 192.168.183.127:2345

3.4、正式调试!介绍几个常用的命令

  (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这个变量的值

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

   (8)  详细的GDB调试命令


4、另外一种调试方法

  让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件,然后使用gdb根据core dump文件找到发生错误的地方

 

  在ARM板上:
  4.1、 ulimit -c unlimited
  4.2、 执行应用程序 : 程序出错时会在当前目录下生成名为core的文件

 

  在PC上:

  4.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
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:
...
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.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

 


推荐阅读
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • Ubuntu安装常用软件详细步骤
    目录1.GoogleChrome浏览器2.搜狗拼音输入法3.Pycharm4.Clion5.其他软件1.GoogleChrome浏览器通过直接下载安装GoogleChro ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • 本文介绍了win7系统休眠功能无法启动和关闭的解决方法,包括在控制面板中启用休眠功能、设置系统休眠的时间、通过命令行定时休眠、手动进入休眠状态等方法。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
author-avatar
xiao1027_333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有