利用GDB来调试程序

常用命令:
GDB常用命令 格式 含义 简写
list List [开始,结束] 列出文件的代码清单 l
prit Print 变量名 打印变量内容 p
break Break [行号或函数名] 设置断点 b
continue Continue [开始,结束] 继续运行 c
info Info 变量名 列出信息 i
next Next 下一行 n
step Step 进入函数(步入) S
display Display 变量名 显示参数
file File 文件名(可以是绝对路径和相对路径) 加载文件
run Run args 运行程序 r
–host参数指的是编译出来的工具运行在什么系统上,我编译出来的gdb是要运行在龙芯1b的开发板上,因此环境就是mipsel-linux的环境,如果你的是arm的开发板,就是arm-linux的环境。
–target为谁编译程序,这个必须要理解明白,比如说我编译出来的gdb要在我的电脑上运行,但是要调试交叉编译出来的mips指令集的程序,这个时候呢,–target就要是mipsel-linux,但是–host是i686-pc-linux-gnu

Gdb编译(7.11):(fail)更改为7.9.1版本
./configure –prefix=/home/book/work/install_software/gdb/gdb-7.9.1/temp_install –target=arm-linux-gnueabihf
Make install 出现如下错误
make[5]: * [gdb.info] Error 127
make[5]: Leaving directory /home/book/work/install_software/gdb/gdb-7.11.1/gdb/doc'
make[4]: *** [subdir_do] Error 1
make[4]: Leaving directory
/home/book/work/install_software/gdb/gdb-7.11.1/gdb’
make[3]: * [install-only] Error 2
make[3]: Leaving directory /home/book/work/install_software/gdb/gdb-7.11.1/gdb'
make[2]: *** [install] Error 2
make[2]: Leaving directory
/home/book/work/install_software/gdb/gdb-7.11.1/gdb’
make[1]: * [install-gdb] Error 2
make[1]: Leaving directory `/home/book/work/install_software/gdb/gdb-7.11.1’
make: * [install] Error 2

1、error: no termcap library found
2、error: makeinfo is required for compilation
解决办法:

sudo apt-get install texinfo
sudo apt-get install libncurses5-dev
sudo apt-get install m4
sudo apt-get install flex
sudo apt-get install bison

以上的错误主要是缺少这些软件造成的,在安装gdb之前执行以上命令,问题解决

Make install
注意看安装完的软件是否是生成的是 arm-linux-gnueabihf-gdb arm-linux-gnueabihf-run 应用程序

  1. 编译gdbserver

修改gdb源码:gdb-7.9.1/gdb/remote.c 文件的 static void process_g_packet (struct regcache *regcache)函数里面修改部分内容,如下:
buf_len = strlen (rs->buf);

/* Further sanity checks, with knowledge of the architecture. */
/* if (buf_len > 2 * rsa->sizeof_g_packet)
error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf);
*/
/modify by xx/
if (buf_len > 2 * rsa->sizeof_g_packet) {
rsa->sizeof_g_packet = buf_len/2;
for (i = 0; i < gdbarch_num_regs(gdbarch); i++) {
if (rsa->regs[i].pnum == -1)
continue;
if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
rsa->regs[i].in_g_packet = 0;
else
rsa->regs[i].in_g_packet = 1;
}

cd gdb/gdbserver/
./configure –host=arm-linux-gnueabihf
make
cp gdbserver /home/book/work/rootfs_min 中
编译要调试的应用,编译时加上-g选项
(编译更高版本的gdbserver,虽然编译过,但在调试时,出现问题,
从开发板的~/work/software/linux-devkit/sysroots/cortexa8hf-vfp-neon-linux-gnueabi/usr/bin$ 中将gdbserver copy到开发板的/usr/bin中(应该与工具链提供的版本是一致的))

Remote ‘g’ packet reply is too long: d85f8780ffffffff88……
省略号(……)表示后面还有一长串16进制数,解决的方法是在进行gdb操作前先在(gdb)后面执行如下语句:
Remote ‘g’ packet reply is too long 解决方法
解决方法
修改gdb/remote.c文件中的static void
process_g_packet (struct regcache *regcache)函数:
由:
if (buf_len > 2 * rsa->sizeof_g_packet)
error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf);
1
2
3
改为:
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[i].pnum == -1)
continue;
if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
rsa->regs[i].in_g_packet = 0;
else
rsa->regs[i].in_g_packet = 1;
}
}
重新编译,安装即可:

Gdb 7.4 版本编译:
修改 remote.c的 代码,再次编译,问题解决。

gdb:
mkdir temp_install
./configure –prefix=$PWD/temp_install –target=arm-arago-linux-gnueabi
make
make install

cp arm-arago-linux-gnueabi-gdb arm-arago-linux-gnueabi-run /home/book/work/crosstool/cross/am335xt3/devkit/bin/ -d

修改 gdbserver的源码,不修改出现 Remote ‘g’ packet reply is too long

cd gdb/gdbserver/
./configure –host=arm-arago-linux-gnueabi –target=arm-arago-linux-gnueabi
make
讲 生成的gdbserver cp到文件系统的 sbin 目录中
Gdb调试的基本知识:
r或run:运行程序。
s或step:进入函数调用
breaktrace(bt):查看各级函数调用及参数
info(i) locals:查看当前栈帧局部变量的值
info break :查看断点信息。
finish:执行到当前函数返回,然后挺下来等待命令
print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
set var:修改变量的值
quit:退出gdb
break(b) 行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
continue(或c):从当前位置开始连续而非单步执行程序
run(或r):从开始连续而非单步执行程序
delete breakpoints:删除所有断点
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X行号:跳至X行
p 变量:打印变量值
n 或 next:单条执行
nfs:server is not responding,still trying 原因与解决方案
mount -t nfs -o nolock,proto=tcp,nfsvers=3 172.20.40.245:/home/book/work_2018 /mnt 指定协议proto=tcp ,证明udp 方式容易丢数据。

set architecture i386:x86-64:intel
请根据实际情况配置,这个问题是GDB调试64位Kernel时才有的。该作者机器上有如下可选参数:
(gdb) set architecture
Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, auto.

调试:
1. 在ARM板上
gdbserver 192.168.1.200:1234 test (开发板的ip ,192.168.1.200,端口号2345,test应用程序名)

  1. 在PC上
    arm-linux-gnueabihf-gdb ./test (test是跟踪的应用程序名)
    输入:target remote 192.168.1.200:1234
    然后: 使用gdb命令来控制程序
    提示 : Remote ‘g’ packet reply is too long: 70ed0100d4000040900200000100000060f901404cf9
    在这里 http://x-slam.com/da_jian_eclipse_qemu_gdb_diao_shi_linux_kernel_huan_jing
    Remote ‘g’ packet reply is too long: d85f8780ffffffff88……
    按照上面的方法,修改gdb-7.9.1/gdb/remote.c ,原因是linux是64位的原因.
    利用ccs的gdb来调试程序(失败)
  2. Ccs中导入带Makefile的工程:
  3. 开发板建立root用户名和密码.
    开发板的etc目录中新建 passwd文件,文件内容如下
    root:x:0:0:root:/root:/bin/sh
    book:123456:0:0:book:/:/bin/sh
    然后 用passwd 设置开发板的root 密码
    2.将编译的7.9.1的gdb程序融入到CCS中

制定交叉编译工具链:

工程的Debug选项配置,Run->DebugConfiguration,选择C/C++Remote Application,点击按钮New launch configuration并命名为gcc_test。
    在Main选项卡里点击上图中下端的SelectOther…选择GDB (DSF) Manual Remote Degugging Launcher。点击OK。
   
    然后进入Debug选项卡,在GDB debugger:一栏里找到移植gdbserver时编译出来的gdb,这里要注意gbdserver一定要与这里的gdb来自同版本,例如我的机器上 gdb安装在了/home/ss/develop_environment/gdb7.1/bin/目录下。GDB command file选择默认即可。
   
    进入Debug的Connection选项卡,输入目标板的IP地址及自定义一个端口号。其他选项默认配置即可,点击Apply并CloseDebug配置页面。
   
    在目标板端执行gdbserver 192.168.1.200:10000 test , 。
   
    在ccs端,点击调试按钮。
   
    然后即进入远程调试界面,从下图看出,在CCS5.2中进行源码调试,输出信息在gdbserver端。需要注意的一点调试完成后一定记得在CCS5.2 Debug模式中点击停止调试按钮,如下图中的红框,因为在gdbserver无法停止一个debugsession。
   

猜你喜欢

转载自blog.csdn.net/tiger15605353603/article/details/81296312