转 C编译: 使用gdb调试
C编译: 使用gdb调试
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

gdb是the GNU Debugger的简称。它是一款UNIX平台的调试器(debugger),可用于为C, C++, Objective-C, Java, Fortran等程序debug。
在gdb中,你可以通过设置断点(break point)来控制程序运行的进度,并查看断点时的变量和函数调用状况,从而发现可能的问题。在许多IDE中,gdb拥有图形化界面。
这里主要介绍gdb的命令行使用,并以C程序为例。测试使用的计算机是Mac OS系统。
启动gdb
下面的有两个C文件。(并没有bug。我们使用gdb来查看程序运行的细节)
程序的一个为test.c,其中有主程序main()。mean.c程序中定义了mean()函数,并在main()中调用。
test.c

#define ARRAYSIZE 4 float mean(float, float); int main()
{
int i;
float a=4.5;
float b=5.5;
float rlt=0.0; float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0};
float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0};
float array_rlt[ARRAYSIZE]; for(i = 0; i < ARRAYSIZE - 1; i++) {
array_rlt[i] = mean(array_a[i], array_b[i]);
} rlt = mean(a, b); return 0;
}

mean.c
float mean(float a, float b)
{
return (a + b)/2.0;
}
使用gcc同时编译上面两个程序。为了使用gdb对进行调试,必须使用-g选项(在编译时生成debugging信息):
$gcc -g -o test test.c mean.c
生成main可执行文件。
(如有必要,使用:
$chmod +x test
来增加用户的执行权限。)
进入gdb,准备调试程序:
$gdb test
进入gdb的互动命令行。
显示程序
我们可以直接显示某一行的程序,比如查看第9行程序:
(gdb) list 9
将显示以第9行为中心,总共10行的程序。我们实际上编译了两个文件,在没有说明的情况下,默认为主程序文件test.c:

4
5 int main()
6 {
7 int i;
8 float a=4.5;
9 float b=5.5;
10 float rlt=0.0;
11
12 float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0};
13 float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0};

如果要查看mean.c中的内容,需要说明文件名:
(gdb) list mean.c:1
可以具体说明所要列出的程序行的范围:
(gdb) list 5, 15
即显示5-15行的程序。
显示某个函数,比如:
(gdb) list mean
设置断点
我们可以运行程序:
(gdb) run
程序正常结束。
运行程序并没有什么有趣的地方。gdb的主要功能在于能让程序在中途暂停。
断点(break point)是程序执行中的一个位置。在gdb中,当程序运行到该位置时,程序会暂停,我们可以查看此时的程序状况,比如变量的值。
我们可以在程序的某一行设置断点,比如:
(gdb) break 16
将在test.c的第16行设置断点。
你可以查看自己设置的断点:
(gdb) info break
每个断点有一个识别序号。我们可以根据序号删除某个断点:
(gdb) delete 1
也可以删除所有断点:
(gdb) delete breakpoints
查看断点
设置断点,并使用run运行程序,程序将运行到16行时暂停。gdb显示:
Breakpoint 1, main () at test.c:16
16 for(i = 0; i < ARRAYSIZE - 1; i++) {
查看断点所在行:
(gdb) list
查看断点处的某个变量值:
(gdb) print a
(gdb) print array_a
查看所有的局部变量:
(gdb) info local
查看此时的栈状态 (反映了函数调用,见Linux从程序到进程):
(gdb) info stack
可以更改变量的值。
(gdb) set var a=0.0
(gdb) set var array_a={0.0, 0.0, 1.0, 1.0}
当程序继续运行时,将使用更改后的值。
如果我们将断点设置在:
(gdb) break mean.c:2
此时栈中有两个a,一个属于main(),一个属于mean()。我们可以用function::variable的方式区分:
(gdb) print mean::a
运行控制
让程序从断点开始,再多运行一行:
(gdb) step
也可以使用下面命令,从断点恢复运行,直到下一个断点:
(gdb) continue
使用run重新开始运行。
帮助
你可以通过gdb的帮助学到更多:
(gdb) help
或者更具体的命令:
(gdb) help info
退出
使用下面命令退出gdb:
(gdb) quit
debug
下面是一个有bug的C程序,demo.c

#include <stdio.h>
struct node {
int element;
};
typedef struct node *PNode;
int main()
{
int i;
PNode np=NULL;
for (i=0; i<10; i++) {
printf("Hello World!");
}
printf("%d \n", np->element);
}

程序可以成功编译,但运行将返回:
Segmentation fault
可以使用gdb来查找问题。
Updata:
经水土精灵提醒: gdb命令可以只输入首字母的缩写,比如c代表continue,b代表break,q代表quit。
转 C编译: 使用gdb调试的更多相关文章
- Linux——【转】gcc编译与gdb调试简要步骤
原文:gcc编译与gdb调试简要步骤 一.Linux程序gcc编译步骤: Gcc编译过程主要的4个阶段: l 预处理阶段,完成宏定义和include文件展开等工作:(.i) l 根据编译参数进行不同程 ...
- gcc编译与gdb调试简要步骤
http://blog.chinaunix.net/uid-24103300-id-108248.html 一.Linux程序gcc编译步骤: Gcc编译过程主要的4个阶段: l 预处理阶段,完成宏定 ...
- gcc编译, gdb调试, makefile写法
//test.c: #include <stdio.h> int main(void) { printf("hello world!"); return 0; } == ...
- 修改,编译,GDB调试openjdk8源码(docker环境下)
在上一章<在docker上编译openjdk8>里,我们在docker容器内成功编译了openjdk8的源码,有没有读者朋友产生过这个念头:"能不能修改openjdk源码,构建一 ...
- C编译: 使用gdb调试
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! gdb是the GNU Debugger的简称.它是一款UNIX平台的调试器(de ...
- 使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误
今天为调试一段代码,使用gcc将程序用-g选项重新编译.但是使用gdb进行debug时,仍然出现“no debug symbols found”的错误.仔细检查了一下Makefile,原来后面定义的连 ...
- Linux下编译ffmpeg并用GDB调试
1.在Ubuntu界面上调处命令行界面,最方便的方式是使用快捷键Ctrl+Alt+T. 2.安装SDL SDL是一个开源的多媒体开发库,可以设置图像和视频的绘制等操作.如果不安装SDL,FFMPEG将 ...
- 8. VIM 系列 - 利用 VIM 8.1 版本编译项目和GDB调试
目录 term 模式 termdebug 模式 VIM版本安装请参考: 0. VIM 系列 - 源码升级最新版本vim term 模式 输入:term 打开此模式,效果如下 这个模式有编辑文本窗口和s ...
- GCC编译UDF和gdb调试UDF
Fluent版本:19.0 前面我们介绍过使用VS来编译和调试UDF,其实我们也可以用GCC来编译UDF.gdb调试UDF.本次介绍的方法更具有通用性,也适用于Linux下Fluent的UDF编译和调 ...
随机推荐
- 专为物联网开发的开源操作系统Contiki(转)
专为物联网开发的开源操作系统Contiki(转) (2012-04-19 15:31:09) 原文网址:http://blog.sina.com.cn/s/blog_6de000c201010z7n ...
- db2常用函数(1)
VALUE函数 语法:VALUE(EXPRESSION1,EXPRESSION2) VALUE函数是用返回一个非空的值,当其第一个参数非空,直接返回该参数的值,如果第一个参数为空,则返回第一个参数的值 ...
- 用excel2010 制作复合图表
用excel2010制作双轴柱线复合图表就是要用excel2010做一个这样的图表:
- JAVA 值传递
Java里方法的参数传递方式只有一种:值传递 值传递:当系统开始执行方法时,系统为形参执行初始化,就是把实参变量的值赋给方法的形参变量,方法的操作的并不是实际的实参变量 引用型变量:系统复制的是变量, ...
- 在chrome浏览器和在IE浏览器中显示的页面样式不一样的解决办法
在IE浏览器中添加 一行代码即可:<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 位 ...
- 【转】如何安装mysql服务
转载地址:http://www.2cto.com/database/201211/168081.html 我刚开始安装mysql的时候,在windows的服务里面可以看到,但是装了以后有一段时间没有 ...
- hihoCoder 数论五·欧拉函数
题目1 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定 ...
- SQL Server 索引和表体系结构(一)
转自:http://www.cnblogs.com/chenmh/p/3780221.html 聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在 ...
- ASP.NET使用后台更改前台Style
首先是后台给前台设置Style属性,设置控件坐标 前台控件: <asp:Label ID = "lblDSRText" Text = "当事人" runa ...
- 《python核心编程》读书笔记--第16章 网络编程
在进行网络编程之前,先对网络以及互联网协议做一个了解. 推荐阮一峰的博客:(感谢) http://www.ruanyifeng.com/blog/2012/05/internet_protocol_s ...