40.Linux应用调试-使用gdb和gdbserver
1.gdb和gdbserver调试原理
通过linux虚拟机里的gdb,来向开发板里的gdbserver发送命令,比如设置断点,运行setp等,然后开发板上的gdbserver收到命令后,便会执行应用程序做相应的动作,来实现调试的功能
和之前学的裸板GDB调试一样,只不过之前学的是在win下的,本次是在linux里的gdb
1.1同样,它们都会需要一个带调试信息的编译文件.
通过Makefile里的arm-linux-gcc -g 来的, -g:表示编译文件里包含gdb调试信息
1.2为什么需要调试信息的编译文件?
比如读开发板的应用程序里的变量a:
首先gdb通过应用程序的带调试信息的编译文件,来找出变量a存的地址位置
然后将地址发送给开发板里的gdbserver,来读出a地址的值
2.安装gdb和gdbserver
首先进入官网下载gdb-7.4: http://ftp.gnu.org/gnu/gdb/
2.1在虚拟机上安装GDB:
# 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
2.2 在开发板上安装GDBServer:
cd gdb/gdbserver/ //在gdb-7.4目录下输入 ./configure --target=arm-linux --host=arm-linux //设GDBServer的工作环境 make //编译
出现以下错误:

指在linux-arm-low.c里,没有找到PTRACE_GETSIGINFO 定义
2.3 解决:
1)
#echo $PATH //来查看PATH环境变量
找到编译器gcc位于/work/tools/gcc-3.4.5-glibc-2.3.6/bin
2)
#cd /work/tools/gcc-3.4.-glibc-2.3./
# grep "PTRACE_GETSIGINFO" * -nR
在gcc根目录下,搜索到在linux/ptrace.h中定义:

3)
#vi linux-arm-low.c
添加: #define PTRACE_GETSIGINFO 0x4202
4)最后重新make,生成gdbserver命令文件
然后将gdbserver命令文件,放入我们开发板的根目录/bin中,便能使用了
cp gdbserver /nfs_root/bin/ //nfs_root:开发板的nfs系统根目录
3.测试程序如下(test_debug.c)
#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 ;
}
其中A2(&a)会调用A2()->C(),然后将a赋值为0x12.
A(p)会调用A()->B()->C(),由于p是个空指针,这里将会出错.
接下来,我们便以这个应用程序为例.
4.编译
#arm-linux-gcc -g -o test_debug test_debug.c //-g:附带调试信息
5.调试test_debug.c
在开发板上:
首先,需要让gdbserver建立本地服务器,以及要测试的哪个文件:
#gdbserver 192.168.2.107: ./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: //与gdbserver建立连接
5.1连接成功,便使用gdb命令来调试
常用命令如下所示(参考http://blog.sciencenet.cn/blog-619295-813770.html):
l
列出所有源代码
break [file]:[row]
打断点,比如:
break test_debug.c: //在test_debug.c文件的第21行处打断点
info br
查看断点
info file
列出当前的文件,共享库。
delete <num>
删除第几个断点,如下图所示:

c
启动程序运行
step
单步执行
next
单步执行,和step不同的是,比如:当前行里有函数调用时,next直接执行下一句,step会进入函数
print a
打印a变量的值
quit
退出gdb
6.也可以通过gdb+coredump来调试test_debug.c
当程序运行出错时,便会生成core文件,并将程序里的运行状况存到core中,也就是coredump,供给gdb来调试
6.1首先,通过ulimit来查看coredump的资源大小
ulimit命令(user limit),主要用来限制用户的各个进程资源.
在开发板里,输入

如上图所示,可以看到coredump的资源大小为0,也就是说,当程序运行出错时,不会生成core文件
6.2设置core文件
设置core文件的资源大小为无限制,输入:
ulimit -c unlimited
//-c:对应coredump
6.3生成core文件
执行:
#./test_debug
出现段错误,并生成core文件,如下图所示:

6.4 进入虚拟机
将core拷贝过来,然后执行:
#/bin/arm-linux-gdb ./test_debug ./core
然后输入bt,便可查看调用关系:

40.Linux应用调试-使用gdb和gdbserver的更多相关文章
- Linux C++调试利器-gdb
在Linux上开发后台C++程序时,没有类似Windows VisualStudio那样强大的可视化IDE.为了提高调试效率,快速定位问题,需要掌握gdb工具的一些基本用法. 添加调试符号信息 co ...
- linux应用调试技术之GDB和GDBServer
1.调试原理 GDB调试是应用程序在开发板上运行,然后在PC机上对开发板上得应用程序进行调试,PC机运行GDB,开发板上运行GDBServer.在应用程序调试的时候,pc机上的gdb向开发板上的GDB ...
- Linux下交叉编译gdb,gdbserver+gdb的使用以及通过gdb调试core文件
交叉编译gdb和gdbserver 1.下载gdb:下载地址为:http://ftp.gnu.org/gnu/gdb/按照一般的想法,最新版本越好,因此下载7.2这个版本.当然,凡事无绝对.我们以gd ...
- [转] linux下的c/c++调试器gdb
PS:1. 断点C++类函数,用b 命名空间::类名::方法名 2. 编译参数一定要加-g,才可断点调试 http://www.cnblogs.com/xd502djj/archive/2012/08 ...
- linux下的c/c++调试器gdb
Reference: http://www.cnblogs.com/xd502djj/archive/2012/08/30/2663960.html linux下的c/c++调试器gdb gdbLi ...
- Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动
姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...
- Linux下交叉编译gdb和gdbserver
平台:tq2440 GCC: gcc version 4.3.3 (Sourcery G++ Lite 2009q1-176) 这里过程中参考了下面两篇博文: http://blog.csdn.ne ...
- 蜂鸟E203系列——Linux调试(GDB+Openocd)
欲观原文,请君移步 本文基于文章<蜂鸟E203系列--利用 Hbrid-E-SDK 环境开发程序> GDB 简介 GDB(GNU Project Debugger),是 GNU 工具链中的 ...
- Linux下调试段错误 (gdb,core,ulimit)
Linux环境下经常遇到某个进程挂掉而找不到原因,我们可以通过生成core file文件加上gdb来定位. (1)首先 在makefile中要增加编译调试选项 -g,才可以利用下面的gdb来调试 gc ...
随机推荐
- Vue源码后记-vFor列表渲染(1)
钩子函数比较简单,没有什么意思,这一节搞点大事情 => 源码中v-for的渲染过程. vue的内置指令包含了v-html.v-if.v-once.v-bind.v-on.v-show等,先从一个 ...
- JavaNIO缓冲区
package com.nio.test; import java.nio.ByteBuffer; import org.junit.Test; /** * * @author fliay * * 一 ...
- defaultView and parentWindow
defaultView 只读的 which is used to represent the currently rendered view of the document 返回的值通常是包含 ...
- HTML DOM应用案例2
<html> <head> <title>day03</title> <script type="text/javascript&quo ...
- Oracle-3 - :超级适合初学者的入门级笔记--用户权限,set运算符,高级子查询
上一篇的内容在这里第二篇内容, 用户权限:创建用户,创建角色,使用grant 和 revoke 语句赋予和回收权限,创建数据库联接 创建用户:create user xxx identified b ...
- 前端面试题(6)图片格式jpg,gif,png-8,png-24的区别,及其各自的使用场景
Gif格式特点: 透明性,Gif是一种布尔透明类型,既它可以是全透明,也可以是全不透明,但是它并没有半透明(alpha透明). 动画,Gif这种格式支持动画. 无损耗性,Gif是一种无损耗的图像格式, ...
- Python的classmethod和staticmethod区别
静态方法(staticmethod) 类方法(classmethod) 静态方法和类方法都可以通过类名.方法名或者实例.方法访问. #-*- coding:utf8 -*- class A(objec ...
- mybatis批量修改
使用mybats经常要用到批量修改或者删除,贴出批量修改的代码.如果是批量删除,可将update换成delete. <update id="changestatus" par ...
- Winwos Server 2012发布ASP.NET MVC5 项目
一.本文实验环境: Windows Server 2012 R2 Visual Studio 2015 项目为:ASP.NET MVC 5.0,使用的是SQL SERVER 2008 R2数据库 二. ...
- input[type='file']样式美化及实现图片预览
前言 上传图片是常见的需求,多使用input标签.本文主要介绍 input标签的样式美化 和 实现图片预览. 用到的知识点有: 1.input标签的使用 2.filelist对象 和 file对象 3 ...