GDB调试-从安装到使用

1、GDB简介

  gdb 工具是 GNU 项目调试器,基于命令行。和其他的调试器一样,我们可以使用 gdb 来一行行的运行程序、单步执行、跳入/跳出函数、设置断点、查看变量等等,它是 UNIX/LINUX 操作系统下强大的程序调试工具。对于一般的Linux桌面系统(例如,ubuntu、centos等),我们可以直接运行gdb来调试程序。

2、GDB源码下载编译和安装

  Linux的各种发行版本一般默认安装有gdb,如果系统上没有安装可以使用以下方法进行安装。
  我们可以在gdb的官网上获取源码,地址为http://www.gnu.org/software/gdb/download/,下载源码gdb-11.2.tar.xz(这里使用的是此版本,其他版本可按需求自行挑选),下载完成后,上存到Ubuntu进行解压:解压命令如下

tar -xvf gdb-11.2.tar.xz	//默认解压到当前文件夹下

![在这里插入图片描述](https://img-blog.csdnimg.cn/f497ef504d9e45e99a2c7d89942d3e48.png

  解压后该文件包含了gdb和gdbserver的源码,如上图所示

3、本机直接安装

//进入到解压后的目录
cd gdb-11.2
//在gdb-11.2目录下生成Makefile文件
//输入命令
./configure
//进行编译
make
//编译完成后 进行安装
make install
//以上过程全是安装默认参数执行编译和安装,可在本机直接使用,如需更改配置和路径,可按一下步骤。
//查看是否安装成功
gdb -v

在这里插入图片描述

  出现相应版本号即安装成功

4、使用方法

  首先编译可执行程序的时候需要加上-g参数,例如:

gcc test.c -g -o test

  此二进制程序test可以直接通过gdb单步调试或直接运行

gdb ./test
//相关命令
r //全速运行
b //增加断点
c //运行到断点函数
s //进入断点函数
u //行号   跳出for循环到指定行
n //单步执行
p buff  //打印相关变量
p sizeof(结构体变量)  //查看结构体占用空间大小
bt //查看堆栈情况使用

  如果二进制程依赖其他库文件

gdb过程中
info sharedlibrary 查看依赖的库文件
看是否找的到
如果找不到将库文件拷贝到其查找路径,或者修改gdb动态搜索路径
命令如下
set sysroot  /home/test/arm_lib

在这里插入图片描述

  此外也可通过进程号或core文件进行调试

//调试进程
gdb -p 进程号 //调试单个进程
//调试core文件
gdb ./可执行程序  core文件

4.1、生成core文件设置

  程序异常退出时,内核会生成一个core文件(是内存映像以及调试信息)。可以通过使用gdb来查看core文件,指示出导致程序出错的代码所在的文件和行数。使用ulimit -c命令可查看core文件的生成开关,若结果为0,则便是关闭了此功能,不会生成core文件。
  设置core空间最大值

ulimit -a//查看core文件或有资源
ulimit -c 大小//设置core文件生成的大小
ulimit -c unlimited //则标识此core文件的大小不受限制
同名core文件新生成的会覆盖旧core文件

  设置core生成路径和名字

//修改文件命令: 
echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
echo "/root/core-%e-%t" > /proc/sys/kernel/core_pattern
%p -添加pid(进程id)
%u - 添加当前uid(用户id)
%g - 添加当前gid(用户组id)
%s - 添加导致产生core的信号
%t -添加core文件生成时的unix时间
%h - 添加主机名
%e -添加导致产生core的可执行程序名

5、gdb移植到嵌入式设备

  在此需要先了解configure相关参数

--build参数是指你编译源码包的系统环境,可以通过查看系统的环境变量来获取,执行set命令可以看到  MACHTYPE=i686-pc-linux-gnu,则--build=i686-pc-linux-gnu(可以不设置该参数,保持默认即可)
 一般情况一般情况下可以不用指定默认即可
 
--host参数指的是编译出来的工具运行在什么系统上,我编译出来的gdb是要运行在arm-linux开发板上,工具链为arm-none-linux-gnueabi
指目标文件运行的平台,一般填入交叉编译链前缀

--target参数指的是编译出的工具所要操作的系统,这个必须要理解明白,比如说我编译出来的gdb要在我的电脑上运行,但是要调试交叉编译出来的arm设备程序,这个时候呢,--target就是arm-none-linux-gnueabi,但是--host是i686-pc-linux-gnu
此参数会将生成目标文件名前缀 带上target所指的的前缀一般情况请下可以不用指定

--program-prefix=PREFIX该参数指定编译后文件安装的目录
--prefix=/xxx/xxx
如果不指定prefix,则可执行文件默认放在/usr/local/bin,
库文件默认放在/usr/local/lib。
配置文件默认放在/usr/local/etc
其他资源文件放在/usr/local/share
卸载这些程序需要在生成Makefile目录下用
make uninstall即可(与make install)操作相反
要么一个一个去手动删除

  因为gdb需要应用到ncurses相关库 因此需要先交叉编译此库。下载地址:http://ftp.gnu.org/gnu/ncurses/

相关参数和路径可按上述自行修改,此处可做参考
(1)tar -zxvf ncurses-5.9.tar.gz //解压到当前目录下
(2)cd ncurses-5.9 //进入解压后目录
(3)./configure --host=arm-none-linux-gnueabi --prefix=$PWD/install --without-ada --enable-termcap --with-shared
(4) make
(5)make install

5.1、ncures编译过程中遇到问题记录

  make install 问题 1

/usr/bin/install: strip process terminated abnormally
Makefile:201: recipe for target 'install.progs' failed
make[1]: *** [install.progs] Error 1
make[1]: Leaving directory '/root/Pwn/tmp/gdb-aarch64/tmux/tmux/ncurses-6.1/progs'
Makefile:113: recipe for target 'install' failed

  方法1问题原因

install.progs问题
问题在于gcc和strip不是同一个arch的。交叉编译时CC已经指定,但是strip依然是系统的strip。强行ln -s软连接指定交叉编译链中的strip
ln -s /mnt/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-strip strip

/usr/bin/strip
还原方法
Ubuntu原来strip文件
strip -> x86_64-linux-gnu-strip
ln -s x86_64-linux-gnu-strip strip

  方法2不使用strip规避此问题

在configure选项中 去掉strip
./configure --host=arm-linux-gnueabihf --prefix=$PWD/libb --disable-stripping --without-ada --enable-termcap --with-shared

  make install 问题 2

/bin/sh ./run_tic.sh
** Building terminfo database, please wait...
Running /usr/bin/tic to install /mnt/hgfs/zpj/GDB/ncurses-5.9/libb/share/terminfo ...

        You may see messages regarding extended capabilities, e.g., AX.
        These are extended terminal capabilities which are compiled
        using
                tic -x
        If you have ncurses 4.2 applications, you should read the INSTALL
        document, and install the terminfo without the -x option.

"terminfo.tmp", line 306, terminal 'lpr': can't link l/lpr to p/printer
? tic could not build /mnt/hgfs/zpj/GDB/ncurses-5.9/libb/share/terminfo
Makefile:86: recipe for target 'install.da`在这里插入代码片`ta' failed
make[1]: *** [install.data] Error 1
make[1]: 离开目录“/mnt/hgfs/zpj/GDB/ncurses-5.9/misc”
Makefile:109: recipe for target 'install' failed
make: *** [install] Error 2

  问题原因

1、 tic工具架构问题:通过find 本机全部tic 通过file查看其架构将x86架构路径添加到环境变量,优先寻找
PATH=/usr/bin:$PATH
2、主机上ncureses版本过低(tic命令由ncureses提供的)
通过编译安装高版本ncuress解决此问题

然后去需要交叉编译的环境中make install
成功之后只需将生成的 lib和include拷贝到设备的相关路径即可(/usr/lib 和/usr/include /usr/bin )

5.2、gdb交叉编译移植

  需要在解压后的源码目录中新建文件夹build用于放置交叉编译后生成的相关文件方便查找(可自行设置其他路径),在gdb-11.2路径下内配置configure生成Makefile

cd gdb-11.2
../configure --host=arm-linux-gnueabihf --prefix=$PWD/build
make
make install

  将新建目录下的 生成的build文件下的bin文件下gdb和gdbserver文件拷贝到设备中完成gdb移植

  ps:时间有限,后续继续补充,如有错误,欢迎指正

猜你喜欢

转载自blog.csdn.net/ZBraveHeart/article/details/127912135