0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

快速入门GDB

汽车电子技术 来源:宅学部落 作者:wit 2023-02-17 09:48 次阅读

GDB简介

常在河边走,哪有不湿鞋。经常编写程序的人,又怎么可能不遇到bug呢?没有遇到过bug的程序员不是真正的程序员。当程序出现了bug,我们就需要debug,常见的程序错误按错误类型来分,一般可分为两种:

  • 编译错误
  • 运行错误

编译错误是指程序在编译阶段遇到的错误,比如语法错误、语义错误等。这种类型的错误编译器一般会帮助我们检查,当遇到此类错误时,编译器就会停止编译,给出错误或警告的信息,我们根据错误的提示,就可以很快解决掉。

运行错误是指程序在运行阶段遇到的错误,比如段错误。在运行阶段,为了能够定位出现的错误,我们经常使用的方法是打印:将程序运行过程中的一些观察变量打印出来,看是否符合正常的程序逻辑。打印方法简单方便,但对于一些隐藏比较深的bug,或者一些跟内存相关的bug,此时再用“打印大法”可能就爱莫能助了。此时,我们经常使用的另一种方法是:单步调试。所谓单步调试,就是我们可以获取到控制程序运行的权限,在人工操作下,程序可以“放慢脚步”,一步一步地执行,甚至可以暂停执行,方便我们观察各个变量、内存、寄存器的值,看是否符合我们的预期。

在Windows下调试程序,我们一般是使用集成开发环境(IDE,Integrated Development Environment )内部集成的调试器(debugger),通过菜单栏的“调试(debug)”选项,就可以让程序进入调试模式:可以单步执行程序、暂停程序运行、观察变量或内存的值。

Linux下调试程序,因为早期没有成熟、好用的IDE,一般都是使用GDB来调试程序。GDB是“GNU Symblic Debugger”的缩写,是GNU自由软件下的一个产品,随着版本不断地更新迭代,目前最新的GDB版本不仅可以调试C语言程序,还可以调试C++、Go、Object-C等编译型语言。

在Linux下开发程序,学会使用GDB是一项基本技能。在Windows下开发程序,在很多IDE内部,往往也集成了GDB,用户可以通过图形界面来调用GDB调试程序,也可以直接在DOS环境下直接通过GDB命令来调试程序。

教程将会带领大家熟悉和掌握程序调试常用的GDB命令,让我们的开发工作更加高效。

GDB安装

很多Linux操作系统默认都已经安装了GDB,所以在安装GDB之前,首先要确实你的当前系统有没有已经安装:

# gdb -v
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

如果出现上面的版本信息,如果GDB已经安装好了;若没有出现上面的信息,可以使用下面的命令直接安装:

# apt-get install gdb  Debian系列操作系统安装命令
# yum install gdb      RedHat系列操作系统安装命令

Linux操作系统因为开源特性,很多操作系统都是基于开源版本不断演化,发展成不同的版本和分支。但总的来说,可以分为三大系:Fedora系、Debian系和SlackWare系。

  • RedHat系:Fedora、RHEL、CentOS等,使用yum命令安装软件包
  • Debian系:Ubuntu、Kali、Knopix等,使用apt-get安装命令
  • SlackWare系:SUSE、OpenSUSE

安装成功后,再次使用# gdb -v 命令查看是否安装成功,如果出现gdb的版本信息,说明软件安装成功。

GDB源码安装

使用yum或apt-get命令,从官方服务器安装的软件包,一般都是稳定版,版本比较旧。如果想尝鲜最先版本的GDB,可以使用源码安装。GDB因为是GNU开源工程,所以安装步骤也是基本的三步:配置、编译、安装。

首先,要到GDB官网下载最新版本的源码包:GDB源码包官网地址

接下来,解压这个源码包,进入源码包目录,按照经典的三步走:配置、编译、安装即可。

# tar xvf gdb-10.1.tar.gz
# cd  gdb-10.1
# ./configure
# make
# make install
# gdb -v
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
...

快速上手

安装好GDB后,接下来就要快速上手GDB的使用。GDB和shell类似,采用命令行形式的命令来调试程序,GDB常用的命令也就10来个,掌握了这些常用的调试命令,基本上就可以满足日常程序的调试需求。

第01步:编译要调试的程序

首先,要将需要调试的源程序编译为可执行文件。以下面的C语言程序为例:

#include 

int main(void)
{
   int sum = 0;
   int i, num;
   
   printf("breakpoint 1\\n");

   printf("input num: ");
   scanf("%d", &num);
   printf("breakpoint 2\\n");

   if(num <= 0)
       printf("input invalid!\\n");
   else
   {
       for(i = 1; i <= num; i++)
           sum += i;
       printf("sum = %d\\n", sum);
   }

   printf("breakpoint 3\\n");
   printf("goodbye!\\n");
   return 0;
}

麻雀虽小,五脏俱全,上面的C语言程序实现了数据求和的简单功能,但包含了程序的三种基本结构:顺序程序结构、选择程序结构和循环程序结构。为方便演示,我们分别在第8行、第12行、第23行设置了三个打印断点的函数。接下来我们编译这个程序:

# gcc -g -O0 main.c -o a.out

生成的可执行文件a.out里都是二进制的机器指令,如果你想要源码级调试,就需要在编译程序时选中:debug选项(-g),生成的debug模式下的可执行文件a.out就包含了各种调试信息,其中最重要的一个信息就是:二进制机器指令和源程序代码之间的对应关系,有了这个调试信息,当程序运行二进制机器指令的时候,就可以实时显示对应的源代码,更方便我们阅读和调试。如果你在编译的时候不使用debug模式,而使用release模式,那么程序在运行时,显示给你的就是二进制的机器代码或汇编指令,不适合人类阅读。

为提高程序的运行效率和性能,编译器在编译程序时,往往会对源程序进行优化,比如常量折叠、缓存、内联展开等。我们在编译程序时,也可以通过参数来控制编译优化级别,一般可分为如下等级:

  • -O0:不对程序进行编译优化,默认的优化等级
  • -O1:可以减少目标文件的体积和程序执行时间
  • -O2:在-O1优化的基础上,编译器不执行循环展开和函数内联,增加了代码的性能
  • -Os:在-O2优化的基础上,专门优化目标文件的大小
  • -O3:在-O2优化的基础上,打开了-finline-functions, -funswitch-loops等标签

源程序经过编译器优化后,生成的二进制和源代码之间可能就不是一一对应的关系了。为了更好的演示源码级调试,我们在编译时选择-O0选项,不对程序进行编译优化。

第02步:进入GDB调试环境

需要调试的可执行程序a.out生成以后,接下来就可以使用gdb进行调试了,可以使用下面的命令来进入GDB调试环境,调试a.out(编译生成的a.out文件位于/home/gdb目录下):

root@ubuntu:/home/gdb# gdb a.out
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later //gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
//www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
   //www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) r
Starting program: /home/gdb/a.out
breakpoint 1
input num: 3
breakpoint 2
sum = 6
breakpoint 3
goodbye!
[Inferior 1 (process 2768) exited normally]
(gdb) q
root@ubuntu:/home/gdb#

当我们使用# gdb a.out时,就会进入交互式的gdb调试环境,运行run(可简写为 r)命令即可启动a.out的运行。程序在运行过程中的输出、输入和正常运行模式下一样,程序结束后,输入quit(可简写为q)命令即可退出GDB调试环境,重新返回到SHELL环境下。

第03步:设置断点、打印变量

GDB作为一个调试器,调试器该有的功能他都有,比如:设置断点、打印变量、单步等。我们在调试程序时,如果想让程序在某行暂停,观察此时的一些寄存器、变量值,此时可以通过GDB的断点设置和变量打印功能来实现。

接下来就给大家演示下如何设置断点和打印变量:

root@ubuntu:/home/gdb# gdb a.out
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) b 8
Breakpoint 1 at 0x11cb: file main.c, line 8.
(gdb) b 12
Breakpoint 2 at 0x1200: file main.c, line 12.
(gdb) b 23
Breakpoint 3 at 0x1252: file main.c, line 23.
(gdb) r
Starting program: /home/gdb/a.out

Breakpoint 1, main () at main.c:8
8     printf("breakpoint 1\\n");
(gdb) print sum
$1 = 0
(gdb) c
Continuing.
breakpoint 1
input num: 3

Breakpoint 2, main () at main.c:12
12     printf("breakpoint 2\\n");
(gdb) c
Continuing.
breakpoint 2
sum = 6

Breakpoint 3, main () at main.c:23
23     printf("breakpoint 3\\n");
(gdb) print sum
$2 = 6
(gdb) c
Continuing.
breakpoint 3
goodbye!
[Inferior 1 (process 2780) exited normally]
(gdb) q
root@ubuntu:/home/gdb#

重新进入GDB调试环境,使用break(可简写为b)命令可以在源代码的具体某一行设置断点。设置好断点后,使用run命令即可运行程序,程序在运行过程中遇到断点会暂停下来,程序暂停后,你可以使用print命令来打印某一个具体变量的值。

如果想要程序继续运行,可以使用continue命令(可简写为c),程序会继续运行,直到遇到下一个断点暂停下来。如果没有再遇到断点,程序则会一直执行下去,直到运行结束。

如果想要程序继续运行,可以使用continue命令(可简写为c),程序会继续运行,直到遇到下一个断点暂停下来。如果没有再遇到断点,程序则会一直执行下去,直到运行结束。

在设置断点的时候,如果想查看某一行代码的具体行数,可以使用list(可简写为l)命令查看部分源代码。多次输入list命令,GDB就会依次显示不同的代码片段,直到你找到要设置的断点的行数为止。

在GDB交互环境下,当你不输入任何命令,直接敲击回车键(Enter键)时,GDB会默认执行上一次你输入的命令。所以,当你需要多次运行同一个命令时,不需要每次都输入相同的命令,直接回车,就可以多次重复执行一个命令了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 运行
    +关注

    关注

    0

    文章

    25

    浏览量

    15345
  • 编译
    +关注

    关注

    0

    文章

    615

    浏览量

    32392
  • DEBUG
    +关注

    关注

    3

    文章

    83

    浏览量

    19446
收藏 人收藏

    评论

    相关推荐

    使用GDB调试Linux应用程序

    本篇讲解使用GDB调试Linux应用程序,以下以 `hellowld.c` 为例介绍 GDB 的调试入门
    发表于 06-27 15:48 337次阅读

    什么是GDBGDB的基本功能和命令总结

    GDB是嵌入式软件工程师调试用的比较多的一种工具,今天就来简单分享一下GDB相关命令。
    的头像 发表于 11-07 09:15 1640次阅读

    gdb使用指南

    gdb使用指南 使用GDB:    本文描述GDB,GNU的原代码调试器。(这是4.12版1994年一月,GDB版本4。16) 目录: * 摘要: &
    发表于 09-28 16:35 27次下载

    gdb的基本工作原理

    gdbGNUdebugger。 gdb的主要功能救死扶伤。 gdb的主要用途修复bug;分析程序结构。 gdb官方网址http://www.gnu.org/software/gdb/
    发表于 04-18 21:18 35次下载

    力控组态软件快速入门

    力控组态软件快速入门,力控组态软件快速入门,力控组态软件快速入门
    发表于 10-30 18:01 0次下载

    实例演示GDB的使用

    GDB简介 GDB(GNU Debugger)是一个强大的命令行调试工具。一般的,在Windows下进行开发,很少操控命令行调试,调试器大多与编译器都集成在IDE里了。 当然,在Windows
    的头像 发表于 10-19 09:58 2350次阅读
    实例演示<b class='flag-5'>GDB</b>的使用

    GDB串行协议概述 GDB Server的作用

    1.概述做嵌入式开发时,很多时候都会使用到GDB,从底层去理解GDB的调试过程,将更加容易的理解调试的过程。 在做嵌入式开发调试时,可理解为两个部分 嵌入式系统平台,启动一个debug stub
    的头像 发表于 08-10 10:10 4815次阅读
    <b class='flag-5'>GDB</b>串行协议概述 <b class='flag-5'>GDB</b> Server的作用

    【嵌入式Linux学习】调试利器之GDB快速入门指南

    1. GDB调试利器1.1. GDB简介在单片机开发中,KEIL、IAR、ADS1.2等集成开发环境下的调试工具对程序开发有很大的帮助, 尤其是出现各种疑难杂症的bug时,往往只能通过单步调试、堆栈
    发表于 11-02 14:06 12次下载
    【嵌入式Linux学习】调试利器之<b class='flag-5'>GDB</b><b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    瑞萨 R8C/2F 入门套件快速入门指南

    瑞萨 R8C/2F 入门套件快速入门指南
    发表于 04-27 19:07 0次下载
    瑞萨 R8C/2F <b class='flag-5'>入门</b>套件<b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    瑞萨入门套件 LCD 应用板快速入门指南

    瑞萨入门套件 LCD 应用板快速入门指南
    发表于 04-28 18:44 0次下载
    瑞萨<b class='flag-5'>入门</b>套件 LCD 应用板<b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    Renesas 7542入门套件快速入门指南

    Renesas 7542 入门套件快速入门指南
    发表于 04-28 19:42 0次下载
    Renesas 7542<b class='flag-5'>入门</b>套件<b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    瑞萨 3803L 入门套件快速入门指南

    瑞萨 3803L 入门套件快速入门指南
    发表于 04-28 19:42 0次下载
    瑞萨 3803L <b class='flag-5'>入门</b>套件<b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    瑞萨 38D5 入门套件快速入门指南

    瑞萨 38D5 入门套件快速入门指南
    发表于 04-28 19:43 0次下载
    瑞萨 38D5 <b class='flag-5'>入门</b>套件<b class='flag-5'>快速</b><b class='flag-5'>入门</b>指南

    GDB调试里怎么设置断点

    本篇讲解使用GDB调试Linux应用程序,以下以 hellowld.c 为例介绍 GDB 的调试入门: 设置断点   disable                 # 禁用所有断点
    的头像 发表于 10-04 16:10 565次阅读

    如何使用linux下gdb来调试python程序

    如何使用linux下gdb来调试python程序  在Linux下,可以使用GDB(GNU调试器)来调试Python程序。GDB是一个强大的调试工具,可以帮助开发者诊断和修复程序中的错误。在本文
    的头像 发表于 01-31 10:41 466次阅读