gdb+gdbserver远程调试技术——环境搭建+调试

对于软件开发来说,调试程序是比不可少的。对于开发PC软件通常系统已经继承了调试工具(比如Linux系统的GDB),或者IDE直接支持对程序的调试。而对于开发嵌入式软件来说调试的手段比较有限,很多开发者仅有的调试手段依然是最原始的打印(我也是其中之一)。当然除了打印调试之外还有通过gdb+gdbserver来调试,gdbserver在目标系统中运行,gdb则在宿主机上运行。

一、源码下载

对于嵌入式软件开发调试工具没有现成的,且嵌入式系统比较繁杂,gdbserver需要根据目标系统单独编译。gdb的源码包下载地址为:http://ftp.gnu.org/gnu/gdb/。目前最新的版本为8.0但由于8.0加入了C++11,而我的目标系统的交叉工具链不支持C++11,故下载7.10版本。

二、编译arm-linux-gdb

Linux系统本身已经自带gdb工具,但无法用在嵌入式调试中,需要单独编译arm-linux-gdb。
  
1.解压源码包

$ tar zxvf gdb-7.10.tar.gz
$ cd gdb-7.10/

2.生成Makefile
进入到源码目录下:

./configure --build=x86_64-linux-gnu --target=arm-gcc6.3-linux-uclibceabi --prefix=/home/a/of/gdb/install --host=x86_64-linux-gnu --with-gnu-ld --enable-plugins --disable-gas --disable-binutils --disable-ld --disable-gold --disable-gprof gdb_cv_prfpregset_t_broken=no

–target:指定目标平台。–prefix:指定安装路径。
 
3.编译

$ make 

4.安装

$ make install

配置环境变量或将arm-linux-gdb拷贝到/usr/bin/目。
vi ~/.bashrc 加入环境变量
source ~/.bashrc

目前只用到bin/目录下的可执行文件gdb,执行下面命令:
$ sudo cp __install/bin/mipsel-linux-gdb /usr/bin/
将生成的gdb改名arm-linux-gdb文件拷贝到系统/usr/bin/目录下,这样便可以在任何地方很方便的调用。

三、编译gdbserver

编译gdbserver不需要执行make install命令,make之后在当前目录下会生成可执行程序gdbserver,将其拷贝到目标系统中。

1.生成Makefile

$ cd gdb/gdbserver/
$ mkdir build
$ cd build
$./configure --build=x86_64-linux-gnu --host=arm-gcc6.3-linux-uclibceabi gdb_cv_prfpregset_t_broken=no

–host:指定交叉工具链,mipsel-linux为我的目标系统的交叉工具链。
(–target=arm-linux表示目标平台,–host表示主机端运行的是arm-linux-gdb,不需要配置–prefix,因为gdbserver不在主机端安装运行)
  
2.编译

$ make
make CC=arm-gcc6.3-linux-uclibceabi-gcc
这一步是指定arm-gcc6.3-linux-gcc的绝对路径,注意,是绝对路径。如果没有错误的话就会在gdbserver的目录下生成gdbserver的可执行文件,注意此时要更改其属性,否则可能会出现无法访问的情况,

#chmod 777 gdbserver将其更改为任何人都可以读写执行;

#arm-gcc6.3-linux-uclibceabi-gcc-strip gdbserver;使用此命令处理一下gdbserver,将多余的符号信息删除,可让elf文件更精简,通常在应用程序的最后发布时使用;然后把它烧写到flash的根文件系统分区的/usr/bin(在此目录下,系统可以自动找到应用程序,否则必须到gdbserver所在目录下运行之),或通过nfs mount的方式都可以。只要保证gdbserver能在开发板上运行就行。

四、 gdb+gdbserver 调试流程

交叉编译,带参数-gstabs或-g加入调试信息。加入要调试的程序是helloworld:

$arm-gcc6.3-linux-gcc -g helloworld.c -o helloworld

然后将生成的可执行文件拷到开发板上:helloworld是欲调试程序,它和gdbserver在同一个目录下:(下面是开发板ip)

gdbserver 192.168.123.221:999 helloworld
1
此时gdbserver开始监听999端口;这个端口号应该是用来和宿主机(PC)进行通讯;

在宿主机上,#export PATH=$PATH:/usr/local/arm-gdb/bin
#arm-gcc6.3-linux-gdb helloworld
(gdb)target remote 192.168.123.221:999
(gdb)c

gdbserver中run命令不能用,可以使用continue, break, print, next, step, list, 等
注:几个常用的调试命令
(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这个变量的值
(6)quit:退出,输入此命令则开发板上的gdbserver也退出

总之总之就是,先把要调试的程序在目标班上./gdbserver <host ip : 端口> helloworld,让gdbserver运行起来;
然后在宿主机上mipsel-linux-gdb helloworld 进入gdb调试的界面;
然后通过(gdb)target remote <target-board-ip:端口> 建立链接;
建立链接后,就可以通信,然后开始调试!

五、eclipse手动调试(自动还没研究成功)
eclipse调试开发板
1、windows菜单-》preferences->C/C++ ->Debug->Gdb选项下:
GDB debugger:设置为mipsel-linux-gdb绝对路径
2、Run->Debug configurations-》双击C/C++ Remote Application新建配置
3、main选项卡最下面点击select other选择using GDB(DSF) manual Remote Debugging Launcher
4、Debugger选项卡下的main选项卡:GDB debugger:设置为mipsel-linux-gdb绝对路径
Debugger选项卡下的connection选项卡:type:TCP;Host name or IP address:192.168.123.221 (开发板IP);Port number:999
5、开发板上运行:gdbserver 192.168.123.221:999 helloworld
6、eclipse上 debug
 

gdb​​​​​​连接qemu时,出现“Remote 'g' packet reply is too long”

1 原因

“Note that other tutorials also add a "-S" parameter so QEMU starts the kernel stopped, however this is ommitted deliberately. The "-S" parameter would allow gdb to set an initial breakpoint anywhere in the kernel before kernel execution begins. Unfortunately, a change made to the gdbserver in QEMU, to support debugging 32- and 16-bit guest code in an x86_64 session breaks the -S functionality. The symptoms are that gdb prints out "Remote 'g' packet reply is too long:", and fails to interact successfully with QEMU. The suggested fix is to run the QEMU until it is in 64-bit code (i.e. after the boot loader has finished and the kernel started) before connecting from gdb (omitting the -S parameter). To debug a running kernel, this is sufficient; it is the method we will take.”

2 解决办法

gdb源码根目录/gdb/remote.c里面,将

if (buf_len > 2 * rsa->sizeof_g_packet)

error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf);

修改为

if (buf_len > 2 * rsa->sizeof_g_packet) {

    rsa->sizeof_g_packet = buf_len ;

    for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {

        if (rsa->regs->pnum == -1)

            continue;

        if (rsa->regs->offset >= rsa->sizeof_g_packet)

            rsa->regs->in_g_packet = 0;

        else  

            rsa->regs->in_g_packet = 1;

    }     

}

也就是说,不是作为error来处理,而是按照下面的处理方式进行处理。

3 cpu是x86_64

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值