源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Linux应用调试使用gdb和gdbserver命令详解

  • 时间:2022-04-26 23:05 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Linux应用调试使用gdb和gdbserver命令详解
[b]1.gdb和gdbserver调试原理[/b] 通过linux虚拟机里的gdb,来向开发板里的gdbserver发送命令,比如设置断点,运行setp等,然后开发板上的gdbserver收到命令后,便会执行应用程序做相应的动作,来实现调试的功能 和之前学的裸板GDB调试 一样,只不过之前学的是在win下的,本次是在linux里的gdb [b]1.1同样,它们都会需要一个带调试信息的编译文件.[/b] 通过Makefile里的arm-linux-gcc  -g 来的,     -g:表示编译文件里包含gdb调试信息 [b]1.2为什么需要调试信息的编译文件?[/b] 比如读开发板的应用程序里的变量a: 首先gdb通过应用程序的带调试信息的编译文件,来找出变量a存的地址位置 然后将地址发送给开发板里的gdbserver,来读出a地址的值 [b]2.安装gdb和gdbserver[/b] 首先进入官网下载gdb-7.4: [url=http://ftp.gnu.org/gnu/gdb/]http://ftp.gnu.org/gnu/gdb/[/url] [b]2.1在虚拟机上安装GDB:[/b]  
# tar xjf gdb-7.4.tar.bz2   //解压
# cd gdb-7.4/    //进入gdb-7.4目录
#./configure --target=arm-linux  
  //GDB需要在pc本机里运行,并调试开发板里的应用程序,所以--target设为arm-linux
#make     //编译
#mkdir tmp    
#make install prefix=$PWD/tmp  //安装到./tmp目录下
sudo cp tmp/bin/arm-linux-gdb /bin/ //复制到/bin目录下
/bin/arm-linux-gdb -v   //-v: 确定一下gdb的版本VID,是否是7.4
[b]2.2 在开发板上安装GDBServer:[/b]
cd gdb/gdbserver/     //在gdb-7.4目录下输入
./configure --target=arm-linux --host=arm-linux  //设GDBServer的工作环境
make  //编译
出现以下错误: [img]http://files.jb51.net/file_images/article/201712/2017121411585514.jpg[/img] 指在linux-arm-low.c里,没有找到PTRACE_GETSIGINFO 定义 [b]2.3 解决:[/b] 1) #echo $PATH     //来查看PATH环境变量 找到编译器gcc位于/work/tools/gcc-3.4.5-glibc-2.3.6/bin 2)
#cd /work/tools/gcc-3.4.5-glibc-2.3.6/    
# grep "PTRACE_GETSIGINFO" * -nR
在gcc根目录下,搜索到在linux/ptrace.h中定义: [img]http://files.jb51.net/file_images/article/201712/2017121411585515.jpg[/img] 3)
#vi linux-arm-low.c
添加: #define PTRACE_GETSIGINFO 0x4202 4)最后重新make,生成gdbserver命令文件 然后将gdbserver命令文件,放入我们开发板的根目录/bin中,便能使用了
cp gdbserver /nfs_root/bin/  //nfs_root:开发板的nfs系统根目录
[b]3.测试程序如下(test_debug.c)[/b]
#include <stdio.h>
void C(int *p)
{
   *p = 0x12;
}
void B(int *p)
{
  C(p);
}
void A(int *p)
{
  B(p);
}
void A2(int *p)
{
  C(p);
}
int main(int argc, char **argv)
{
  int a;
  int *p = NULL;
  A2(&a); // A2 > C
  printf("a = 0x%x\n", a);
  A(p); // A > B > C
  return 0;
}
其中A2(&a)会调用A2()->C(),然后将a赋值为0x12. A(p)会调用A()->B()->C(),由于p是个空指针,这里将会出错. 接下来,我们便以这个应用程序为例. [b]4.编译[/b]
#arm-linux-gcc -g -o test_debug test_debug.c //-g:附带调试信息
[b]5.调试test_debug.c[/b] 在开发板上: 首先,需要让gdbserver建立本地服务器,以及要测试的哪个文件:
#gdbserver 192.168.2.107:2345 ./test_debug
//192.168.2.107:本地IP地址
//2345:端口号,用来让gdb来连接用的
//./test_debug:要测试的哪个文件
在虚拟机上:
#/bin/arm-linux-gdb ./test_debug // 启动gdb,指定调试文件为test_debug
#target remote 192.168.2.107:2345 //与gdbserver建立连接
[b]5.1连接成功,便使用gdb命令来调试[/b] 常用命令如下所示(参考[url=http://blog.sciencenet.cn/blog-619295-813770.html]http://blog.sciencenet.cn/blog-619295-813770.html[/url]): 列出所有源代码 break [file]:[row] 打断点,比如: break test_debug.c:21     //在test_debug.c文件的第21行处打断点 info br 查看断点 info file 列出当前的文件,共享库。 delete <num> 删除第几个断点,如下图所示: [img]http://files.jb51.net/file_images/article/201712/2017121411585516.png[/img] c 启动程序运行 step 单步执行 next  单步执行,和step不同的是,比如:当前行里有函数调用时,next直接执行下一句,step会进入函数 print a 打印a变量的值 quit 退出gdb [b]6.也可以通过gdb+coredump来调试test_debug.c[/b] 当程序运行出错时,便会生成core文件,并将程序里的运行状况存到core中,也就是coredump,供给gdb来调试 [b]6.1首先,通过ulimit来查看coredump的资源大小     [/b] ulimit命令(user limit),主要用来限制用户的各个进程资源. 在开发板里,输入 [img]http://files.jb51.net/file_images/article/201712/2017121411585517.png[/img] 如上图所示,可以看到coredump的资源大小为0,也就是说,当程序运行出错时,不会生成core文件 [b]6.2设置core文件[/b] 设置core文件的资源大小为无限制,输入:
ulimit -c unlimited
 //-c:对应coredump
[b]6.3生成core文件[/b] 执行: #./test_debug 出现段错误,并生成core文件,如下图所示: [img]http://files.jb51.net/file_images/article/201712/2017121411585518.png[/img] [b]6.4 进入虚拟机[/b] 将core拷贝过来,然后执行:
#/bin/arm-linux-gdb ./test_debug ./core
然后输入bt,便可查看调用关系: [img]http://files.jb51.net/file_images/article/201712/2017121411585519.png[/img] [b]总结[/b] 以上所述是小编给大家介绍的Linux应用调试使用gdb和gdbserver命令详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程素材网网站的支持!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部