Linux应用调试 :使用gdb和gdbserver进行远程调试
一.引言
在日常程序开发中不免遇到类似空指针操作导致程序崩溃的问题,所以需要一定的手段去定位bug,而断点调试是普遍使用的技巧,比如Windows中用VC++的debug模式进单步运行、断点调试等,而且是图形化操作界面很友好,但在Linux系统中使用的是没有图形界面的调试工具-GDB(听说eclipse支持GUI调试,暂未尝试),所以需要通过指令进行操作,下面逐步介绍gdb调试环境的搭建和使用方法。
二.gdb调试环境搭建
(1)下载gdb工具源码:http://www.gnu.org/software/gdb/download/

选择下载最新版本:

注:由于个人本地arm-linux-gcc版本较低(4.4.3)不支持 C++11,后面下载编译的是 gdb-7.12
(2)解压
解压tar.gz文件:tar -zxvf xxx.tar.gz
解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。
(3)编译安装
--------①编译gdb(在Linux主机上运行的工具)
./configure --target=arm-linux //配置要调试的目标为arm-Linux开发板(前提已经配置了arm-linux-gcc交叉编译环境)
make
make install //默认安装路径可以在Makefile中看到:prefix = /usr/local
也可以指定安装目录,比如 : make install prefix=$PWD/tmp

环境变量添加该路径 或 复制arm-linux-gdb到/bin目录下后便可作为系统工具使用。

错误1:
location.c:527:19: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
|| *argp == '\0'
解决方法: || *argp == '\0' 修改为 || *argp == NULL
错误2:
make[]: 进入目录“/home/sheldon/work/linux_project/gdb-8.2/gdb/doc”
/home/sheldon/work/linux_project/gdb-8.2/missing makeinfo --split-size= --split-size= -I ./../../readline/doc -I ./../mi -I . \
-o gdb.info ./gdb.texinfo
/home/sheldon/work/linux_project/gdb-8.2/missing: : /home/sheldon/work/linux_project/gdb-8.2/missing: makeinfo: not found
WARNING: 'makeinfo' is missing on your system.
You should only need it if you modified a '.texi' file, or
any other file indirectly affecting the aspect of the manual.
You might want to install the Texinfo package:
<http://www.gnu.org/software/texinfo/>
The spurious makeinfo call might also be the consequence of
using a buggy 'make' (AIX, DU, IRIX), in which case you might
want to install GNU make:
<http://www.gnu.org/software/make/>
make[]: *** [gdb.info] 错误
make[]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb/doc”
make[]: *** [subdir_do] 错误
make[]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb”
make[]: *** [install-only] 错误
make[]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb”
make[]: *** [install] 错误
make[]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb”
make[]: *** [install-gdb] 错误
make[]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2”
make: *** [install] 错误
sheldon@sheldon-vm:~/work/linux_pro
解决方法:sudo apt-get install texinfo (或者从GNU下载源码自行编译安装:http://ftp.gnu.org/gnu/texinfo/)
--------②编译gdbserver(在Linux开发板上作为父进程运行,启动加了gdb调试信息的应用程序)
cd gdb/gdbserver/ //继续进入到gdbserver目录
./configure --host=arm-linux //配置要运行的平台为arm-Linux开发板
make
make install prefix=../../tmp/gdbserver //指定安装到之前的tmp目录下

将编译生成的gdbserver通过nfs或usb复制到开发板上,后面就可以开始远程gdb调试了!
三.调试方法
(1)编写测试程序:
#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 ;
}
编译生成可执行文件(-g选项增加gdb调试信息):
arm-linux-gcc test_debug.c -g -o test_debug
(2)发现在ARM板上运行test_debug后产生段错误,接下来就启动gdbserver来定位问题:
gdbserver 192.168.1.17: ./test_debug //开发板通过gdbserver执行test_debug,并开启网络端口监听
(3)在PC上执行
/bin/arm-linux-gdb ./test_debug //读取应用程序
target remote 192.168.1.17: //通过开发板监听的网络端口传输控制指令

然后便可使用gdb命令来远程控制程序运行进行调试:
示例①:main函数入口打个断点,然后继续运行:

示例②:在代码的31行处打断点,然后继续运行:

示例③:进入函数A2执行C(p),然后继续进入函数C到*p = 0x12(此时该语句还未执行),打印*p的随机值为33620,再继续执行赋值操作后打印值为赋值的0x12即十进制18:

更详细的使用方法可参考如下指令自行调试:
|
命令 |
命令缩写 |
命令说明 |
|
list |
l |
显示多行源代码 |
|
break |
b |
设置断点,程序运行到断点的位置会停下来 |
|
info |
i |
描述程序的状态 |
|
run |
r |
开始运行程序 |
|
display |
disp |
跟踪查看某个变量,每次停下来都显示它的值 |
|
step |
s |
执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句 |
|
next |
n |
执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句) |
|
|
p |
打印内部变量值 |
|
continue |
c |
继续程序的运行,直到遇到下一个断点 |
|
set var name=v |
设置变量的值 |
|
|
start |
st |
开始执行程序,在main函数的第一条语句前面停下来 |
|
file |
装入需要调试的程序 |
|
|
kill |
k |
终止正在调试的程序 |
|
watch |
监视变量值的变化 |
|
|
backtrace |
bt |
产看函数调用信息(堆栈) |
|
frame |
f |
查看栈帧 |
|
quit |
q |
退出GDB环境 |
后面运行到操纵空指针处便打印了相关异常信息,这样就能大致定位出具体哪条语句处出现问题:

四.另一种调试方法(非单步调试):
让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件,然后使用gdb根据core dump文件找到发生错误的地方,具体步骤如下:
(1)在ARM板上进行如下操纵:
ulimit -c unlimited //一般Linux系统不会产生core dump文件(默认大小0),所以需要对core文件重新设置大小
./test_debug //程序出错时会在当前目录下生成名为core的文件
如下就是产生了core文件:

(2)将core文件复制到PC上进行如下操纵:
/bin/arm-linux-gdb ./test_debug ./core
执行后便可看到程序终止的信息并提示了具体出错位置:

另外也可以通过 bt 指令打印函数调用信息(堆栈) main->A->B->C,然后到第6行异常终止:

以上便是gdb调试的一般方法,更灵活的操作技巧需要多参考相关资料加以实践~
-end-
Linux应用调试 :使用gdb和gdbserver进行远程调试的更多相关文章
- 微信公众号开发系列教程一(调试环境部署续:vs远程调试)
http://www.cnblogs.com/zskbll/p/4080328.html 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试 ...
- 40.Linux应用调试-使用gdb和gdbserver
1.gdb和gdbserver调试原理 通过linux虚拟机里的gdb,来向开发板里的gdbserver发送命令,比如设置断点,运行setp等,然后开发板上的gdbserver收到命令后,便会执行应用 ...
- tomcat开发远程调试端口以及利用eclipse进行远程调试
一.tomcat开发远程调试端口 方法1 WIN系统 在catalina.bat里: SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compi ...
- 移动前端调试方案(Android + Chrome 实现远程调试)
一:背景 通常情况我们调试移动端页面最常用的方法就是:切换pc端浏览器的userAgent来模拟手机或其他移动设备调试页面 然后用手机打开要调试的页面 刷新页面查看调试结果 但是这就存在两个问题 在p ...
- chrome://inspect 移动前端调试方案(Android + Chrome 实现远程调试)
一:背景通常情况我们调试移动端页面最常用的方法就是:切换pc端浏览器的userAgent来模拟手机或其他移动设备调试页面 然后用手机打开要调试的页面 刷新页面查看调试结果 但是这就存在两个问题 在pc ...
- Mobile Web 调试指南(2):远程调试
原文:http://blog.jobbole.com/68606/ 原文出处: 阿伦孟的博客(@allenm ) 第一篇中讲解了如何让手机来请求我们开发电脑上的源码,做到了这步后,我们可以改完代码立即 ...
- 调试环境部署续:vs远程调试
原文http://www.bitscn.com/weixin/464994.html 第一步 IIS的配置 进入iis,点击网址,选择你的网站,在窗口的右边编辑网站中点击绑定,如图所示. 进入网站绑 ...
- gdbserver远程调试嵌入式linux应用程序方法
此处所讲的是基于gdb和gdbsever的远程调试方法.环境为:PC机:win7.虚拟机:10.04.下位机:飞嵌TE2440开发板. 嵌入式linux应用程序的开发一般都是在linux里面编写好代码 ...
- [转] linux下的c/c++调试器gdb
PS:1. 断点C++类函数,用b 命名空间::类名::方法名 2. 编译参数一定要加-g,才可断点调试 http://www.cnblogs.com/xd502djj/archive/2012/08 ...
随机推荐
- armv8 memory translation
AArch32,arm的32bit架构: AArch64,arm的64bit架构: ARMv8.2-LPA,是armv8.2中的新feature,扩大了IPA和PA的支持范围,从48bit扩展到52b ...
- 今天整理了一下Winform用的UI插件信息
平时主要用了一下几个比较好的UI控件: 1:IrisSkin2 皮肤插件.这是一款与编程开发相关的素材资源,主要是提供一些采用IrisSkin2.dll控件进行软件窗口换肤的素材文件,包括一些GIF图 ...
- [openjudge-贪心]删数问题
题目描述 题目描述 键盘输入一个高精度的正整数N,去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N和k,寻找一种方案使得剩下的数字组成的新数最小. 输出应包括所去掉的数 ...
- win10安装JDK
1.下载 首先,在官网下载 JDK:Oracle 官网 如上图所示,在 Oracle 官网下载 JDK,有一点需要注意,那就是在咱们下载合适的 JDK 之前,需要先点击“标记1”所在的按钮,选择接受. ...
- Kubernetes持久化存储1——示例
目录贴:Kubernetes学习系列 一.简介 存储管理与计算管理是两个不同的问题.Persistent Volume子系统,对存储的供应和使用做了抽象,以API形式提供给管理员和用户使用.要完成这一 ...
- P1605 迷宫
P1605 迷宫 这是一道毒瘤题... 这是一道广搜题 bfs ... 代码: #include<cstdio> #include<iostream> #include< ...
- 【数据使用】3k水稻数据库现成SNP的使用
---恢复内容开始--- 我们经常说幻想着使用已有数据发表高分文章,的确,这样的童话故事每天都在发生,但如何走出第一步我们很多小伙伴不清楚,那么我们就从水稻SNP数据库的使用来讲起. http://s ...
- [Python]基础教程(3)、Python基础语法
Python 标识符 在 Python 里,标识符由字母.数字.下划线组成. 在 Python 中,所有标识符可以包括英文.数字以及下划线(_),但不能以数字开头. Python 中的标识符是区分大小 ...
- jenkins安装部署全过程
基本配置: 1.Linux安装配置jdk环境 1.1.上传到 Linux 服务器:例如: 上传至: cd /usr/local 1.2.解压: rpm -ivh jdk-8u111-linux-x64 ...
- linux centos7添加ip黑名单禁止某个ip访问
centos7用的是firewall 添加单个黑名单只需要把ip添加到 /etc/hosts.deny 格式 sshd:$IP:deny vim /etc/hosts.deny 添加你要禁止的i ...