• 40.Linux应用调试-使用gdb和gdbserver


    1.gdb和gdbserver调试原理

    通过linux虚拟机里的gdb,来向开发板里的gdbserver发送命令,比如设置断点,运行setp等,然后开发板上的gdbserver收到命令后,便会执行应用程序做相应的动作,来实现调试的功能

    和之前学的裸板GDB调试 一样,只不过之前学的是在win下的,本次是在linux里的gdb

    1.1同样,它们都会需要一个带调试信息的编译文件.

    通过Makefile里的arm-linux-gcc  -g 来的,     -g:表示编译文件里包含gdb调试信息

    1.2为什么需要调试信息的编译文件?

    比如读开发板的应用程序里的变量a:

    首先gdb通过应用程序的带调试信息的编译文件,来找出变量a存的地址位置

    然后将地址发送给开发板里的gdbserver,来读出a地址的值

     

    2.安装gdb和gdbserver

    首先进入官网下载gdb-7.4: http://ftp.gnu.org/gnu/gdb/ 

    2.1在虚拟机上安装GDB:  

    # tar xjf gdb-7.4.tar.bz2                  //解压
    
    # cd gdb-7.4/                              //进入gdb-7.4目录
    
    #./configure --target=arm-linux         
                  //GDB需要在pc本机里运行,并调试开发板里的应用程序,所以--target设为arm-linux
    
    #make                                      //编译
    
    #mkdir    tmp                            
    
    #make install prefix=$PWD/tmp              //安装到./tmp目录下
    
    sudo cp tmp/bin/arm-linux-gdb  /bin/       //复制到/bin目录下
    
    /bin/arm-linux-gdb  -v                     //-v: 确定一下gdb的版本VID,是否是7.4

    2.2 在开发板上安装GDBServer:

    cd gdb/gdbserver/                                   //在gdb-7.4目录下输入
    
    ./configure --target=arm-linux --host=arm-linux              //设GDBServer的工作环境
    
    make             //编译

    出现以下错误:

    指在linux-arm-low.c里,没有找到PTRACE_GETSIGINFO 定义

    2.3 解决:

    1) 

    #echo $PATH     //来查看PATH环境变量

    找到编译器gcc位于/work/tools/gcc-3.4.5-glibc-2.3.6/bin

    2)

    #cd /work/tools/gcc-3.4.5-glibc-2.3.6/    
    # grep "PTRACE_GETSIGINFO"  *  -nR

    在gcc根目录下,搜索到在linux/ptrace.h中定义:

     

    3)

    #vi linux-arm-low.c

    添加: #define PTRACE_GETSIGINFO 0x4202

    4)最后重新make,生成gdbserver命令文件

    然后将gdbserver命令文件,放入我们开发板的根目录/bin中,便能使用了

    cp  gdbserver  /nfs_root/bin/          //nfs_root:开发板的nfs系统根目录

    3.测试程序如下(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
    ", a);
      A(p);    // A > B > C
      return 0;
    }

    其中A2(&a)会调用A2()->C(),然后将a赋值为0x12.

    A(p)会调用A()->B()->C(),由于p是个空指针,这里将会出错.

    接下来,我们便以这个应用程序为例.

    4.编译

    #arm-linux-gcc -g -o test_debug test_debug.c   //-g:附带调试信息

    5.调试test_debug.c

    在开发板上:

    首先,需要让gdbserver建立本地服务器,以及要测试的哪个文件:

    #gdbserver 192.168.2.107:2345 ./test_debug
    //192.168.2.107:本地IP地址
    //2345:端口号,用来让gdb来连接用的
    //./test_debug:要测试的哪个文件

    在虚拟机上:

    #/bin/arm-linux-gdb   ./test_debug    // 启动gdb,指定调试文件为test_debug
    
    #target remote  192.168.2.107:2345    //与gdbserver建立连接

    5.1连接成功,便使用gdb命令来调试

    常用命令如下所示(参考http://blog.sciencenet.cn/blog-619295-813770.html):

    l

    列出所有源代码

    break [file]:[row]

    打断点,比如:

    break test_debug.c:21     //在test_debug.c文件的第21行处打断点

    info br

    查看断点

    info file

    列出当前的文件,共享库。

    delete <num>

    删除第几个断点,如下图所示:

     

    c

    启动程序运行 

    step

    单步执行

    next  

    单步执行,和step不同的是,比如:当前行里有函数调用时,next直接执行下一句,step会进入函数

    print a

    打印a变量的值

    quit

    退出gdb

    6.也可以通过gdb+coredump来调试test_debug.c

    当程序运行出错时,便会生成core文件,并将程序里的运行状况存到core中,也就是coredump,供给gdb来调试

    6.1首先,通过ulimit来查看coredump的资源大小     

    ulimit命令(user limit),主要用来限制用户的各个进程资源.

    在开发板里,输入

     

    如上图所示,可以看到coredump的资源大小为0,也就是说,当程序运行出错时,不会生成core文件

    6.2设置core文件

    设置core文件的资源大小为无限制,输入:

    ulimit -c unlimited
     //-c:对应coredump

    6.3生成core文件

    执行:

    #./test_debug

    出现段错误,并生成core文件,如下图所示:

     

    6.4 进入虚拟机

    core拷贝过来,然后执行:

    #/bin/arm-linux-gdb ./test_debug ./core

    然后输入bt,便可查看调用关系:

     

  • 相关阅读:
    map,forEach,some,every,filter条件过滤的区别
    dangerouslySetInnerHTML空格不换行解决方案
    react项目里link语法报错Dangerous property 'dangerouslySetInnerHTML'
    如何判断两个数组是否相等相等
    react hooks的缺点(针对状态不同步和没有生命周期)
    面试聊啥
    Win10 PIN码是什么?如何设置?
    三个环形图(万一是n个呢)
    Chrome 离线加装扩展的新方法
    java安装
  • 原文地址:https://www.cnblogs.com/lifexy/p/8034277.html
Copyright © 2020-2023  润新知