C编译: 使用gdb调试

简介: 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!    gdb是the GNU Debugger的简称。它是一款UNIX平台的调试器(debugger),可用于为C, C++, Objective-C, Java, Fortran等程序debug。

作者: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。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
3月前
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
58 10
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
3月前
|
NoSQL
技术分享:如何使用GDB调试不带调试信息的可执行程序
【8月更文挑战第27天】在软件开发和调试过程中,我们有时会遇到需要调试没有调试信息的可执行程序的情况。这可能是由于程序在编译时没有加入调试信息,或者调试信息被剥离了。然而,即使面对这样的挑战,GDB(GNU Debugger)仍然提供了一些方法和技术来帮助我们进行调试。以下将详细介绍如何使用GDB调试不带调试信息的可执行程序。
88 0
|
5月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
40 1
|
5月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
30 0
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试正在运行的程序
Linux C/C++ gdb调试正在运行的程序
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试core文件
Linux C/C++ gdb调试core文件
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试
Linux C/C++ gdb调试
|
6月前
|
NoSQL Ubuntu 测试技术
【GDB自定义指令】core analyzer结合gdb的调试及自定义gdb指令详情
【GDB自定义指令】core analyzer结合gdb的调试及自定义gdb指令详情
93 1
|
6月前
|
NoSQL 编译器 C语言
【GDB调试技巧】提高gdb的调试效率
【GDB调试技巧】提高gdb的调试效率
77 1