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。

时间: 2024-10-12 12:06:17

C编译: 使用gdb调试的相关文章

gcc编译, gdb调试, makefile写法

//test.c: #include <stdio.h> int main(void) { printf("hello world!"); return 0; } ====================================== 一. 1. 编译过程:预处理(processing)->编译(compilation)->汇编(assembly)->Linking 2. 预处理: gcc -E test.c -o test.i / gcc -E t

gcc编译与gdb调试简要步骤

http://blog.chinaunix.net/uid-24103300-id-108248.html 一.Linux程序gcc编译步骤: Gcc编译过程主要的4个阶段: l 预处理阶段,完成宏定义和include文件展开等工作:(.i) l 根据编译参数进行不同程度的优化,编译成汇编代码(.s.S) l 用汇编器把汇编代码进一步生成目标代码(.o) l 用连接器把生成的目标代码和系统或用户提供的库连接起来,生成可执行文件 格式: l gcc -E test.c//预处理阶段 l Gcc -

使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误

今天为调试一段代码,使用gcc将程序用-g选项重新编译.但是使用gdb进行debug时,仍然出现“no debug symbols found”的错误.仔细检查了一下Makefile,原来后面定义的连接选项中指定了-s.gcc的文档中说明如下: -sRemove all symbol table and relocation information from the executable. 去掉-s后,可以用gdb进行调试了

使用gcc编译gdb调试

gcc 在linux系统中,默认是没有安装gcc编译器的,可以通过命令 rpm -q | grep gcc 来查看.安装命令为: yum -y install gcc 安装后,编写一个.c结尾的文件. gcc test.c 就会默认输出一个a.out的输出文件,这个输出文件就是可执行文件. 如果加上-o选项,则可以自定目标文件. gcc -o test test.c test就是它的可执行文件. 一般都默认加上-Wall 选项,可以自动提示一些出错警告的信息. gcc -Wall -o test

gdb调试

[前言]使用gdb调试前,在编译程序时,要加 -g 选项,否则你将看不见程序的函数名.变量名,所代替的全是运行时的内存地址. 1.开始调试 a.  gdb <program> program也就是你的执行文件,一般在当前目录下. b. gdb <program> core 用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件. 2.[列出源码],从第n行开始(编译时要加 -g 选项) l n 3.[设置断点]在第N行加断点 break

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

GDB调试汇编堆栈

GDB调试汇编堆栈 准备工作 终端编译工具: 编译64位Linux版本32位的二进制文件,需要安装一个库,使用指令sudo apt-get install libc6-dev-i386 测试代码: test.c 分析过程 1.生成汇编代码:gcc -g gdbtest.c -o gdbtest -m32 2.调试:gdb test 3.设置断点,因为目的是分析而不是调试bug,所以我们将断点设置在main函数 4.开始gdb调试:r(un),如若想获取此时的汇编代码,可用指令:disassemb

GDB调试汇编分析

GDB调试汇编分析 代码 本次实践我参照了许多先做了的同学的博客,有卢肖明,高其,张梓靖同学.代码借用的是卢肖明同学的代码进行调试运行. GCC编译 使用gcc -g gdbtest.c -o gdbtest -m32命令在64位的机器上产生32位汇编代码 在使用gdb进行调试运行时,有cgdb和gdb两种工具,我建议大家使用张梓靖同学使用的cgdb工具,因为使用时可以随时看到自己的源代码,看到我们的断点在哪里,每一步返回值到了哪行,更加直观. 分析过程 使用b main指令在main函数处设置

20145234黄斐《信息安全系统设计基础》GDB调试汇编堆栈过程分析(1)

堆栈跟踪 首先编辑一个程序 用gcc编译,再使用gdb调试,发现gdb尚未下载 下载后重新运行gdb 设置断点:b+行号或者"main" 运行:r frame:打印出的信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句. info frame:打印出的信息:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的.函数参数地址及值.局部变量的地址等等. 输入命令disassemble:显示出该代码(main())的汇编形式 info