arm嵌入式gdb移植和搭建远程gdb调试运行环境

简介: arm嵌入式gdb移植和搭建远程gdb调试运行环境

文章目录

概述

gdb移植Linux嵌入式板子上单独运行

移植准备

编译移植ncurse库:

编译移植gdb6.8:

测试:

gdb远程调试运行环境部署

下载gdb

编译gdb

编译PC端

编译开发板端

测试实现

遇到的问题


概述

  • 在Linux下调试C/C++执行程序,不可避免需要用到调试工具,有些时候总是依赖打印debug很难快速定位问题,这时候就体现了gdb的重要性了。
  • 一般桌面系统如Ubuntu、Centos等可以直接运行gdb + 目标可执行程序, 而嵌入式系统则分情况, 如果性能强劲且调试的源码文件比较少, 也可以编译嵌入式版的gdb执行文件, 即嵌入式gdb + 目标可执行程序(只需要将gdb移植到板子上即可)。如果性能弱或者调试对象的源码文件多可通过网络通信采用分离法, 即PC端运行gdb, 同时源码也在PC端, 而目标可执行程序放到开发板, 开发板端运行gdbserver, 与PC端的gdb进行网络通信(远程gdb调试方式,只需要将交叉编译好的gdbserver移植到板子上备有即可)。PC端也称客户端, 开发板端为服务端, gdbserver 接收 gdb 所传送的命令(list, step等), 然后调度执行文件, 并把相关信息反馈给PC端, PC端解析后查询源码文件并显示到控制台(这种方式对于一些性能较弱运行不起来gdb的板子来说只能如此进行远程调试)。
  • 注意,远程gdb调试除了可执行文件外还需要源码! 而我的源码文件比较多, 所以采用后者即 gdb + gdbserver。 在介绍安装前, 请确保宿主机和目标机可以相互ping通且可以telnet访问端口, 因为两者是靠网络通信的!

本篇文章将就这两种嵌入式gdb使用环境进行准备


  • gdb移植嵌入式板子上单独运行。
  • gdb远程调试运行环境部署。

gdb移植Linux嵌入式板子上单独运行

移植准备

  • 此处使用的是5.6版本;
  • 此处使用的是6.8版本;

编译移植ncurse库:

  • 下载tar包后,解压;
tar -xvf ncurses-5.6.tar.gz


  • 进入文件目录;
./configure --host=arm-cortex_a9-linux-gnueabi --prefix=`pwd`/_install --without-ada --enable-termcap --with-shared


  • 配置、生成Makefile,注意–prefix指定的是目标目录,即编译完成后生成的文件的位置;
  • 20191221192531281.png
make
make install
• 1
• 2

20191221193634677.png

  • 将编译好的_install中的文件移植到arm板子上的Linux系统下的对应路径下即可。

编译移植gdb6.8:

  • 下载tar包后,解压;
tar -xvf gdb-6.8a.tar.gz


  • 进入文件目录;
./configure --host=arm-cortex_a9-linux-gnueabi CC=/opt/toolchis/bin//arm-cortex_a9-linux-gnueabi-gcc --enable-shared --prefix=$PWD/_output --disable-werror --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext LDFLAGS="-L/home/ww/ARM/gdb/ncurses-5.6/_install/lib" CPPFLAGS="-I/home/ww/ARM/gdb/ncurses-5.6/_install/include"
(具体解释请看下面tips)
make CFLAGS=-static
make install

20191221194203424.png

  • 报错:error: field ‘siginfo’ has incomplete type

20191221200550917.png

  • 通过查找发现是这个结构体定义不正确,网上建议修改gdb源码,这里直接下载了gdb-7.6.1.tar.gz版本重新编译,网上有人说这个版本能够很好解决这个问题。更换版本重复之前操作。
  • 正常编译完成了。20191221214128514.png20191221214244928.png
  • tips:


  • 先看上面第3步中的参数:"CC=XXX"指定交叉编译器(这里使用了绝对路径,之前移植其他库的时候没有使用绝对路径导致无法查找到使用的编译器);
  • "–enable-shared…“这里指定的一系列开关项,可以在参考链接中查看具体含义,这里不再赘述;值得注意的是一项:”–disable-werror"这一项可以屏蔽werror报警,这一项也是本人遇到的错误的根源所在;
  • "LDFLAGS=XXX"指定的是前面交叉编译完成的ncurse的lib目录的路径;"CPPFLAGS=XXX"指定的是前面交叉编译完成的ncurse的include目录的路径;

测试:

  • 中间报错找不到动态库,改为静态连接重新编译后没问题,将_output目录下的bin、lib、include目录下的文件都复制到板子系统下即可使用。

20191221230726617.pnggdb远程调试运行环境部署

下载gdb

  • 搭建arm嵌入式板子上的gdb运行环境需要在Linux PC机上准备以下步骤:
  • 下载gdb源码包:ftp://ftp.gnu.org/gnu/gdb,这里我选择的是 gdb-6.8a.tar.gz
  • 提前在Linux PC机上准备好交叉编译工具链:arm-linux-gcc等工具可用.
  • 编译gdb
tar jxvf gdb-6.8a.tar.bz2

编译PC端

//编译PC端 gdb
cd gdb-6.8/
mkdir _install
./configure --target=arm-cortex_a9-linux-gnueabi --disable-werror --prefix=/home/ww/ARM/gdb/gdb-7.6.1/_install //没有设置host 默认= x86_64
make
make install

20191221214514340.png

20191221215524262.png

20191221215605328.png

编译开发板端

  • 进入gdb/gdbserver目录下执行:
//编译开发板端 gdbserver
cd gdb-6.8/gdb/gdbserver
./configure --host=arm-cortex_a9-linux-gnueabi
make //当前路径就有gdbserver

20191221215924588.png

20191221220044908.png

测试实现

  • 编写一段C的测试demo:
#include <stdio.h>
void debug(char *str)
{
    printf("debug info :%s\n",str );
}
main(int argc,char *argv[])
{
    int i,j;
    j=0;
    for(i=0;i<10;i++){
        j+=5;
        printf("now a=%d\n", j);
    }
}


arm-cortex_a9-linux-gnueabi-gcc gdb_test.c -o gdb_test 生成gdb_test 可执行文件, 连同 gdb-6.8/gdb/gdbserver/gdbserver 一并拷贝到开发板, 然后运行

./gdbserver :8899 /home/gdb_test
  • 报错:应该是gdbserver编译时使用了动态库,重新添加CFLAGS=-static选项重新编译gdbserver20191221221456621.png


* 重新编译后执行:

20191221222120571.png

  • 当然也可以指定允许哪个IP地址访问, 比如我的PC 192.168.0.104 访问开发板,运行


./gdbserver 192.168.0.104:8899 /home/a.out
  • PC端把可执行文件和源码拷贝到gdb-6.8/_install/bin下,运行:
fuzk@ubuntu:~/tools/gdb/gdb-6.8/_install/bin$ ./arm-none-linux-gnueabi-gdb
GNU gdb 6.8
Copyright (C) 2008 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=x86_64-unknown-linux-gnu --target=arm-none-linux-gnueabi".
(gdb) target remote 172.16.30.20:777  重中之重!
Remote debugging using 172.16.30.20:777
[New Thread 319]
0xb6efced0 in ?? ()
(gdb) b main
No symbol table is loaded.  Use the "file" command.
(gdb) file a.out 
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from /home/fuzk/tools/gdb/gdb-6.8/_install/bin/a.out...done.
(gdb) b main
Breakpoint 1 at 0x846c: file test.c, line 11.
(gdb) c
Continuing.
Breakpoint 1, main (argc=1, argv=0xbe8d4e54) at test.c:11
         j=0;
(gdb) n
         for(i=0;i<10;i++){
(gdb) n                  这里发生异常, 直接执行完, 同时开发板也打印全部, 猜测是版本问题
Program exited with code 012.
(gdb) 
开发板log:
/data/app/MAINAPP/data # ./gdbserver 172.16.2.212:777 /data/a.out
[ 7431.399932] c0 init: untracked pid 318 exited
Process /data/a.out created; pid = 319
Listening on port 777
Remote debugging from host 172.16.2.212
now a=5
now a=10
now a=15
now a=20
now a=25
now a=30
now a=35
now a=40
now a=45
now a=50
Child exited with retcode = a 
Child exited with status 10
GDBserver exiting
  • gdb-6.8的PC端gdb貌似有问题, 无法全部单步调试, 我的交叉编译器是arm-none-linux-gnueabi-gcc, 同时也提供了arm-none-linux-gnueabi-gdb, 发现调试正常, 跟我自己编译的区别在于版本是7.2, 所以应该是版本问题, 后续用系统自带的,其log如下:
fuzk@ubuntu:~/test/gdb/simple$ arm-none-linux-gnueabi-gdb
GNU gdb (Sourcery CodeBench Lite 2012.03-57) 7.2.50.20100908-cvs
Copyright (C) 2010 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-none-linux-gnueabi".
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>.
(gdb) target remote 172.16.30.20:777
Remote debugging using 172.16.30.20:777
0xb6ed7ed0 in ?? ()
(gdb) b main
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (main) pending.
(gdb) b main
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (main) pending.
(gdb) file a.out 
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from /home/fuzk/test/gdb/simple/a.out...done.
Cannot access memory at address 0x0
(gdb) b main
Cannot access memory at address 0x0
Note: breakpoints 1 and 2 also set at pc 0x846c.
Breakpoint 3 at 0x846c: file test.c, line 11.
(gdb) c
Continuing.
Breakpoint 1, main (argc=1, argv=0xbe9bbe54) at test.c:11
         j=0;
(gdb) s
         for(i=0;i<10;i++){
(gdb) s
             j+=5;
(gdb) s
             printf("now a=%d\n", j);
(gdb) n
         for(i=0;i<10;i++){
(gdb) s
             j+=5;
(gdb) s
             printf("now a=%d\n", j);
(gdb) n
         for(i=0;i<10;i++){
(gdb) n
             j+=5;
(gdb) n
             printf("now a=%d\n", j);
(gdb) n
         for(i=0;i<10;i++){
(gdb) n
             j+=5;
(gdb) n
             printf("now a=%d\n", j);
(gdb)
(gdb) s
         for(i=0;i<10;i++){
(gdb) s
             j+=5;
(gdb) s  printf由于没有-g编译 调用step会导致异常, 所以建议使用next, 但如果用系统自带的会有上面红色提示 所以用step也不怕!
             printf("now a=%d\n", j);
(gdb) s
         for(i=0;i<10;i++){
(gdb) s
             j+=5;
(gdb) s
             printf("now a=%d\n", j);
=====================
对应开发板:
/data/app/MAINAPP/data # ./gdbserver 172.16.2.212:777 /data/a.out
[ 8046.924774] c0 init: untracked pid 326 exited
Process /data/a.out created; pid = 327
Listening on port 777
Remote debugging from host 172.16.2.212
now a=5
now a=10
now a=15
now a=20
now a=25

遇到的问题

igure: error: no termcap library found
  Makefile:10927: recipe for target 'configure-gdb' failed
  make[1]: *** [configure-gdb] Error 1
  make[1]: Leaving directory '/home/fuzk/tools/gdb/gdb-7.2'
 缺少 termcap库, 先安装该库: https://ftp.gnu.org/gnu/termcap/
      tar zxvf termcap-1.3.1.tar.gz
      cd termcap-1.3.1/
      ./configure --prefix=/home/fuzk/tools/gdb/gdb-7.2/_install --target=arm-none-linux-gnueabi
      vi Makefile :     
        CC = /opt/toolchain/arm-2012.03/bin/arm-none-linux-gnueabi-gcc 
        AR = /opt/toolchain/arm-2012.03/bin/arm-none-linux-gnueabi-ar
      make install
  重初始化: 
  CFLAGS=-I/home/fuzk/tools/gdb/gdb-7.2/_install/include LDFLAGS=-L/home/fuzk/tools/gdb/gdb-7.2/_install/lib ./configure --prefix=/home/fuzk/tools/gdb/gdb-7.2/_install --target=arm-none-linux-gnueabi --host=arm-none-linux-gnueabi
  make


相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
1月前
|
数据处理
基于ARM的嵌入式原理与应用:ALU的功能与特点
基于ARM的嵌入式原理与应用:ALU的功能与特点
|
3月前
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
62 10
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
3月前
|
NoSQL
技术分享:如何使用GDB调试不带调试信息的可执行程序
【8月更文挑战第27天】在软件开发和调试过程中,我们有时会遇到需要调试没有调试信息的可执行程序的情况。这可能是由于程序在编译时没有加入调试信息,或者调试信息被剥离了。然而,即使面对这样的挑战,GDB(GNU Debugger)仍然提供了一些方法和技术来帮助我们进行调试。以下将详细介绍如何使用GDB调试不带调试信息的可执行程序。
103 0
|
5月前
|
存储 Ubuntu 编译器
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
|
5月前
|
Ubuntu Unix Linux
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(一)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(一)
|
5月前
|
Linux 编译器 语音技术
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(二)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(二)
|
4月前
|
机器学习/深度学习 人工智能 计算机视觉
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
|
5月前
|
存储 算法 Linux
详细解读ARM嵌入式整理
详细解读ARM嵌入式整理
36 0
|
1月前
|
编解码 弹性计算 应用服务中间件
阿里云服务器Arm计算架构解析:Arm计算架构云服务器租用收费标准价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中Arm计算架构以其低功耗、高效率的特点受到广泛关注。本文将深入解析阿里云Arm计算架构云服务器的技术特点、适用场景以及包年包月与按量付费的收费标准与最新活动价格情况,以供选择参考。