《嵌入式 Linux C 语言应用程序设计(修订版)》一2.4 嵌入式Linux调试器GDB的使用

简介:

本节书摘来自异步社区《嵌入式 Linux C 语言应用程序设计(修订版)》一书中的第2章,第2.4节,作者 孙琼,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.4 嵌入式Linux调试器GDB的使用

嵌入式 Linux C 语言应用程序设计(修订版)
在程序编译通过生成可执行文件之后,就进入了程序的调试环节。调试一直来是程序开发中的重中之重,如何使程序员能够迅速找到错误的原因是一款调试器的目标。

GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具,它是一种强大的命令行调试工具。

一个出色的调试器需要有以下几项功能。

能够运行程序,设置所有能影响程序运行的参数。
能够让程序让指定的条件下停止。
能够在程序停止时检查所有参数的情况。
能够根据指定条件改变程序的运行。

2.4.1 GDB使用实例

下面通过一个简单的实例使读者对GDB有一个感性的认识,这里所介绍的指令都是GDB中最为基本也是最为常用的指令,希望读者能够动手操作,掌握GDB的使用方法。 首先,有以下程序段。

include <stdio.h>

/*子函数add:将自然数从1~m相加*/
int add(int m)
{
           int i,n=0;
           for(i=1; i<=m;i++)
                n += i;
           printf("The sum of 1-%d in add is %d\n", m,n);
}

int main()
{
        int i,n=0;
        add(50);
        for(i=1; i<=50; i++)
             n += i;
        printf("The sum of 1-50 is %d \n", n );
}

注意将此程序用GCC进行编译时要加上“-g”选项。

1.进入GDB
进入GDB只需输入GDB和要调试的可执行文件即可,如下所示:

[root@localhost gdb]# gdb test
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)

可以看出,在GDB的启动画面中指出了GDB的版本号、使用的库文件等信息,接下来就进入了由“(gdb)”开头的命令行界面了。

2.查看文件
在GDB中键入‘l’(list)就可以查看所载入的文件,如下所示:

(gdb) l
4       {
5               int i,n=0;
6               for(i=1; i<=m;i++)
7                  n += i;
8               printf("The sum of 1-%d in add is %d\n", m,n);
9       }
10
11      int main()
12      {
13           int i,n=0;
(gdb) l
14           add(50);
15           for(i=1; i<=50; i++)
16            {
17              n += i;
18            }
19           printf("The sum of 1-50 is %d \n", n );
20       
21      }
22

可以看出,GDB列出的源代码中明确地给出了对应的行号,这样可以大大地方便代码的定位。

注意 在一般情况下,源代码中的行号与用户书写程序中的行号是一致的,但有时由于用户的某些编译选项会导致行号不一致的情况,因此,一定要查看在GDB中的行号。
3.设置断点
设置断点可以使程序到一定位置暂停它的运行,程序员在该位置处可以方便地查看变量的值、堆栈情况等,从而找出代码的症结所在。

在GDB中设置断点非常简单,只需在“b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点),其命令如下所示:

(gdb) b 6
Breakpoint 1 at 0x804846d: file test.c, line 6.
要注意的是,在GDB中利用行号设置断点是指代码运行到对应行之前暂停,如上例中,代码运行到第5行之前暂停(并没有运行第5行)。

4.查看断点处情况
在设置完断点之后,用户可以键入“info b”来查看设置断点情况,在GDB中可以设置多个断点。

(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0804846d in main at test.c:6

5.运行代码
接下来就可运行代码了,GDB默认从首行开始运行代码,可键入“r”(run)即可,在“r”后面加上行号即可从程序中指定行开始运行。

(gdb) r
Starting program: /home/yul/book/test 

Breakpoint 1, add (m=50) at test.c:6
6               for(i=1; i<=m;i++)

可以看到,程序运行到断点处就停止了。

6.查看变量值
在程序停止运行之后,程序员需要查看断点处的相关变量值。在GDB中只需键入“p+变量值”即可,如下所示:

(gdb) p n
$1 = 0
(gdb) p i
$2 = 134518440

在此处,为什么变量“i”的值为如此奇怪的一个数字呢?原因就在于程序是在断点设置的对应行之前停止的,那么在此时,并没有把“i”的数值赋为0,而只是一个随机的数字。但变量“n”是在第5行赋值的,故在此时已经为0。

小技巧 GDB在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作“$N”,而无需写冗长的变量名。
7.观察变量
在某一循环处,程序员往往希望能够观察一个变量的变化情况,这时就可以键入命令“watch”来观察变量的变化情况,如下所示:

(gdb) watch n
Hardware watchpoint 2: n

可以看到,GDB在“n”设置了观察点。

注意 在此处必须键入完整的命令“watch”,因为在GDB中有不少以‘w’开头的命令,如“where”、“while”等。
8.单步运行
单步运行是指一次只运行一条语句,这样可以方便程序员来查看程序运行的结果,在此处只需键入“n”(next)即可。

(gdb) n
7                  n += i;
(gdb) n
Hardware watchpoint 2: n

Old value = 15
New value = 21

可以看到,随着程序的单步运行,当“n”的值发生变化时,GDB就会自动显示出n的变化情况。

9.程序继续运行
命令“c”(continue)可以使GDB继续运行以下的程序,程序在再次遇到断点时停止,如下所示:

(gdb) c
Continuing.
The sum of 1-50 is 1275 

Program exited with code 031.
10.退出GDB
退出GDB只需使用指令“q”(quit)即可,如下所示:

(gdb) q
[root@localhost gcc]

到此为止,使用GDB的整体过程已经结束了。以上所讲述的命令是GDB中最为常见的命令,下面几节将会详细讲解GDB的命令。

2.4.2 设置/删除断点

GDB中有丰富的断点设置、删除命令,可以满足用户各个方面的需求。表2.8列出了GDB中常见的断点设置及删除命令。


80713dfe0b23bce2588424c03cebcf2357f19402

小知识 在多线程的程序中,观察点的作用很有限,gdb只能观察在一个线程中的表达式的值。如果用户确信表达式只被当前线程所存取,那么使用观察点才有效。gdb不能注意一个非当前线程对表达式值的改变。

2.4.3 数据相关命令

在GDB中也有丰富的数据显示相关命令,他们可以使用户可以以各种形式显示所要查看的数据,数据相关命令如表2.9所示。


32a6bf0eab8fdb3d5abd811dfd3621f3e1287c09

小技巧 在使用print命令时,可以对变量按指定格式进行输出,其命令格式为:print /变量名+格式其中格式有以下几种方式。
X:十六进制;d:十进制;u:无符号数;o:八进制;
T:二进制;a:十六进制打印;c:字符格式;f:浮点数。

2.4.4 调试运行环境相关命令

在GDB中控制程序的运行也是非常方便地,用户可以自行设定变量值、调用函数等,其具体命令如表2.10所示。


4e197e162deab3b1ff97a0c63afff6fd64f3601c

2.4.5 堆栈相关命令

gdb中也提供了多种堆栈相关的命令,可以查看堆栈的情况、寄存器的情况等,其具体命令如表2.11所示。


31a3c7cf1e794f491eae2899bc0d3213d097e274
相关实践学习
阿里云图数据库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 调试
64 10
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
102 3
|
3月前
|
NoSQL Linux 编译器
内核实验(一):使用QEMU+GDB断点调试Linux内核代码
如何配置环境并使用QEMU虚拟机结合GDB进行Linux内核代码的断点调试,包括安装QEMU、交叉编译工具链,编译内核以及通过GDB远程连接进行调试的详细步骤。
156 0
内核实验(一):使用QEMU+GDB断点调试Linux内核代码
|
3月前
|
NoSQL C语言
【C语言】GDB使用
【C语言】GDB使用
23 1
|
3月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
180 0
|
3月前
|
算法 IDE 程序员
C语言与嵌入式系统:嵌入式C编程基础。
C语言与嵌入式系统:嵌入式C编程基础。
75 0
|
4月前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
|
5月前
|
存储 移动开发 C语言
技术心得记录:嵌入式开发中常用到的C语言库函数
技术心得记录:嵌入式开发中常用到的C语言库函数
58 1
|
5月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
44 1
|
5月前
|
NoSQL 编译器 Linux
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
90 0
下一篇
无影云桌面