研究下linux下使用gdb+eclipse调试arm程序

因为现在公司的板子都是将什么都编译好,然后下载进入板子,然后运行看看printf打印输出,从输出中查找问题,个人觉得这样子的效率奇低,结合自己以前写单片机程序的经验来看,个人觉得最好的方法应该在eclipse中能够完成所有操作.gdb足够强大,但是命令行界面实在太尴尬.不直观.这里我尝试下在本地ubuntu14.04搭建一个环境看看效果.

1 编译器在虚拟机中编译源码

  • 先压缩下源码,这源码很大,小文件很多,如果不压缩,传输一天都搞不定.
  • 继续把编译器一起给弄过去,解压到指定目录,并同时把环境变量给弄了.
  • 在home目录下建立jet文件夹(为了和编译服务器保持一致,他这是用elbox的记录了很多绝对路径.),并解压源码
  • 由于openssl需要被其他所有引用,所以要预先编译,这样就可以编译其他相关程序了.

2 搭建eclipse运行环境

先下载,链接如下: http://mirrors.opencas.org/eclipse/technology/epp/downloads/release/neon/3/eclipse-cpp-neon-3-linux-gtk.tar.gz
同时还需要安装java: 这里百度java就可以直接安装.找那个自己机器对应的就可以了

这里安装java参考了教程 : http://blog.csdn.net/zgrjkflmkyc/article/details/9263119

这里概括下要点:

  • 解压并将相关文件复制到 /usr/lib/java/jre1.8.0_131 中

  • 设置环境变量: /etc/environment 添加如下信息

      JAVA_HOME="/usr/lib/java/jre1.8.0_131"
      CLASSPATH="$JAVA_HOME/lib"
      PATH="$JAVA_HOME/bin"    //这里注意是添加到原来的PATH中去.不要删除原来的path了.
    
  • 创建连接

      sudo update-alternatives --install /usr/bin/java java /usr/lib/java/jre1.8.0_131/bin/java 300
    
  • 配置java(有多个JAVA的情况,如果只有一个就不用配置了)

       sudo update-alternatives --config java
    
  • 查看是否安装成功

      java -version 
    

安装eclipse测试
按照以上链接下载好了eclipse,解压就可以运行了,正常选择创建一个c project就可以.需要选择CROSS gcc 同时正确填写相关的编译工具链.

重点来了:

配置 run -> Debug Configuration(先配置成手动模式[需要自行敲命令进入,而不是全部自动化的一个过程])

  1. 双击 C/C++ Remote Application 新建一个配置,eclipse会更具当前选择的项目初始化大部分配置项.这里我们只需要修改Debugger配置项.
  2. 在右下方点击”Select Other”,选择”GDB(DSF) Maual Remote Debugging Launcher”确认.
  3. 选择进入Debugger配置页,在Main标签中,GDB debugger 填写找到自己编译的gdb程序,(因为没有填入环境变量,所以这里就弄成绝对路径).
  4. 在Debugger中找到connection 标签,Type 选择TCP,并填写目标板上gdbserver的IP和端口号.所有配置好过后就可以点apply进行保存配置.关掉配置窗口.再稍微摸索下就可以发现如何进入调试模式了.(需要下位机先运行好,调试服务器就可以直接搞事了)

配置成完全自动的模式(需要完整版的ssh,太占用FW的空间了,要等段时间搞)

3 重新用编译器编译gdbserver

先到官网上下载gdb程序,这里我先现在了8.0的.但是编译的时候提示说要支持c++ 11的编译器,这里我发现我的gcc均在4.8以上,应该是支持的,无奈换上了7.3试试看.以后再继续研究gdb8.0看看.编译使用的时候发现ubuntu14.04上带的是7.7.1,但是无论使用本机还是自己编译生成的gdb均无法使用,都是说arm端回复的东西太长了不知道啥意思.(但是我重新编译test,用本机工具链编译,使用本机gdb调试完全正常,所以我这里再去下载一下gdb7.7.1进行测试下看看效果)

安装过程主要参考了这篇文章: http://www.cnblogs.com/lijinlei/p/4850432.html

途中遇到了许多问题,包括有下面几个

  1. 在bdfio.c 中有一段 memset(x,0,sizeof(x)),类似的函数编译不过,我改了.(最后这个版本没有用)
  2. 先make 再 make install才会在prefix目录中出现编译成功后的相关文件(这里执行make install的时候也报错了(7.3))
  3. 实在搞不懂是些什么鬼问题,这里就直接按照系统的gdb版本来看.换到了7.7.1这个版本,看起来这个版本是2014年5月的.
  4. 按照下面的演示编译一遍,这下次编译过程很顺畅,啥问题也没有.关于依赖项的话我按照上面教程的连接给弄上去了一部分,还有一部分没有的我也没管.
  5. 实际使用的时候会遇到一些问题,有一个一旦远端调试器连接上去就会报一下 “Remote ‘g’ packet reply is too long”,这里我参考了: http://blog.csdn.net/u013592097/article/details/70549657 这位大师的,修改了源码.果然编译一遍.好用的很.

编译过程:

  1. 先将源码解压,然后进入到源码目录下并执行以下代码(这里我的编译器是 arm-openwrt-linux-gcc )

     ./configure --target=arm-openwrt-linux --program-prefix=arm-openwrt-linux- --prefix=/home/jetli/gdb7.3
     make 
     make install 
    
  2. 正常的话,在/home/jetli/gdb7.3目录中将会出现相关的几个目录出来.但是我这里执行make install的时候报了错误.具体什么忘记了,但是gdb7.3目录中的文件没啥问题

  3. 开始编译gdbserver了.这个程序就是运行在arm端的程序.

     cd gdb/gdbserver 
     CC=arm-openwrt-linux-gcc ./configure --host=arm-openwrt-linux --target=arm-openwrt-linux
     make 
    
  4. 此时就会在该目录下生成gdbserver文件了.这里可以使用file命令看看是否是给arm程序使用的.

     file gdbserver
     #gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
    
  5. 去掉符号信息,这样子可以让gdbserver文件小很多,这里实测可以从800K变成230KB左右.

     arm-openwrt-linux-strip gdbserver -o gdbserver1 
     //生成的文件可以直接使用了.
    

4 正常使用

在arm端:

在arm端直接执行下面的就可以了:

./gdbserver 192.168.0.91:5000 test
//192.168.0.91 是gdb调试器所在的IP.  test是需要调试的文件.

在调试器端*

一般交叉编译都是在这上面完成的,所以应该先是编译程序.这里我写了一个test.c的程序进行测试.程序使用arm-openwrt-linux-gcc 进行添加调试信息编译:

arm-openwrt-linux-gcc -o test test.c -g

生成的文件直接加载到gdb调试器中去:

./arm-openwrt-linux-gdb test
 target remote 192.168.0.55:5000

正常到这里就可以直接运行程序了,查阅相关文档可以学习相关命令进行调试.

这里遇到一个问题就是使用run的时候这边显示远端不支持.使用continue命令可以.打好断点过后就可以直接调试.n下一步什么.用起来虽然没有GUI的舒服,但是总归可以使用了.

5 尝试加上eclipse联合调试看看效果.

由于全自动化的部署调试需要完整版的ssh才可以,所以现在目前可以想到的办法就是往fw中添加完整版的ssh.但是这个是后话了.这里最好可以先远程的方式将手动化的调试给搞定.

现在看来普通的程序调试起来没有任何问题,但是如有其他类型的应用程序(多线程)的,需要慢慢琢磨下如何调试是最好的.

这里说下转换eclipse 环境遇到的问题,死活都发现本地上使用的arm-openwrt-linux-gcc 是正常的,编译都能过,在eclipse上死活都说命令找不到,只需要修改下:

project->properties->c/c++ build->environment  在PATH中添加自己编译器所在的路径就可以了.

事实证明,联合调试效果很好,是出乎意料的好,现在想看哪里的变量,想在哪里打断点,想搞事就搞事,但是就是复制自己生成的文件到目标机器上的时候比较麻烦,这里可以直接搭建下tftp服务器,将makefile 中添加一个install 将生成的必要文件赋值到tftp服务器目录中去.然后写一个脚本放在目标机器上,运行脚本就可以下载相关文件并开启调试模式,这样子的效率也很高.虽然没有全自动化的高,但是由于全自动化的需要完全体的ssh,这个ssh在我们的项目中实现起来有点麻烦.所以这里等我差不多把eclipse给摸懂了再继续深入搞事..

总结

有一个IDE进行调试效率会快很多.但是大家都喜欢速度快的IDE,像Eclipse本身就比较慢,再跑在虚拟机里面,这就更慢了.如果能有办法让其跑在windows下面就更好了.这里想到一个思路 eclipse+cygwin(arm-linux-gcc)+linux(服务器)+arm(开发板) ,以后将继续在这方面还有全自动部署调试方面进行深入学习.

    原文作者:爪爪熊
    原文地址: https://www.jianshu.com/p/a792751ca956
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞